Compare commits
317 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b4f96ed45e | |||
| 1a3f9f72cf | |||
| bc46f7c0c3 | |||
| bec46a9ba2 | |||
| e57caefd09 | |||
| 7e99f6bc5f | |||
| a85caaee1d | |||
| 5b00aaf561 | |||
| 174f11bdbd | |||
| 05442bdb11 | |||
| 9ba3cea2b1 | |||
| 20d48289b8 | |||
| 8f9410ceff | |||
| 3a08dd7dde | |||
| cfb858a51c | |||
| 37d7fdbcae | |||
| 62c14e9437 | |||
| 90b8346312 | |||
| 167d6a08f8 | |||
| 649d68a00f | |||
| 8807cd06b7 | |||
| b533d57717 | |||
| 14a6269243 | |||
| 7b96190e6c | |||
| 010b75251f | |||
| da3f3fd1fb | |||
| 26e13b4f5f | |||
| a771fcb397 | |||
| 64a6fbe39f | |||
| 43b860d267 | |||
| 818df50bb5 | |||
| 2570911283 | |||
| f59a448f3f | |||
| 834712bb58 | |||
| d98f739043 | |||
| aa5dc5455e | |||
| dfc970c926 | |||
| 68ecf340c5 | |||
| 3d626e84ef | |||
| 95abf768a7 | |||
| cb00190c3e | |||
| 8fdf1b23a3 | |||
| 2e9405db4c | |||
| fe5828cb47 | |||
| e56d8db6a3 | |||
| e76b6e3f27 | |||
| 9a7ce2fd29 | |||
| 462b93f62c | |||
| f71f67c4ff | |||
| 8358bda133 | |||
| 85199e200b | |||
| 5681801b85 | |||
| 86ef07b166 | |||
| 00339cb99b | |||
| daf3760cd4 | |||
| c1450ad616 | |||
| 025a09ed87 | |||
| 1716db14ed | |||
| d0e171784c | |||
| a68983b551 | |||
| c7c0139788 | |||
| 37bc2b3bb9 | |||
| c85806c422 | |||
| ee98683538 | |||
| a822d990d2 | |||
| 33d3303bdf | |||
| 8b35df8327 | |||
| 0854ed2b51 | |||
| 713c1a7a86 | |||
| fb816a0eb9 | |||
| fff62df6a2 | |||
| e6a07e80d7 | |||
| 514a98321d | |||
| 36ac35361f | |||
| bc7d728eb3 | |||
| 66a43c35db | |||
| e9f057c91b | |||
| 196cdfafa6 | |||
| 590ca7115f | |||
| 650db9c962 | |||
| 5d7c454e52 | |||
| 4d5f98017f | |||
| 7ecf6cb014 | |||
| 9d1aebce74 | |||
| dc9671c639 | |||
| 93bfe8164c | |||
| d6329eaa1a | |||
| f21a3069a5 | |||
| a8b989b51d | |||
| 142bfb5250 | |||
| 334327df67 | |||
| 2400210144 | |||
| 1b1c300aad | |||
| 531b03e7af | |||
| 650c1c64f1 | |||
| 2fd4726919 | |||
| b86745ee4e | |||
| c04aa05398 | |||
| 3c9bab8563 | |||
| 0dc24799f1 | |||
| 6eb1786635 | |||
| bbf2a97d2e | |||
| 00c6a589a5 | |||
| c7dca1dbef | |||
| 1da732bbf5 | |||
| 00b0311c86 | |||
| 6a707f515e | |||
| c0409a819e | |||
| b2b5f564a1 | |||
| d54c2dd39a | |||
| e668ecd453 | |||
| 0020359b8f | |||
| a0176775ff | |||
| a18fddb831 | |||
| ea462ae7d7 | |||
| 6d14583f28 | |||
| 956117a74f | |||
| 0c1d4e43e4 | |||
| ae156801df | |||
| 844e09c40e | |||
| 81da93a302 | |||
| e0508c6c64 | |||
| db9618ac2f | |||
| a38182b967 | |||
| 474bd7beaf | |||
| d8c449aadf | |||
| 2c611ec0ba | |||
| b44f5e59ac | |||
| 0ad0510624 | |||
| d2fb69cda3 | |||
| 2047cb8d1d | |||
| 24f9f06279 | |||
| b671bb72dc | |||
| af11ad6253 | |||
| 0d9b89fb34 | |||
| 80fee5ac1e | |||
| a909bd6edd | |||
| eeb4d4d4de | |||
| 4c42043940 | |||
| 6136abd0f8 | |||
| 69a5f3d58b | |||
| 98ef419abd | |||
| 77354f0f90 | |||
| 108f87c08f | |||
| 08e2698b9c | |||
| 6e81db7b43 | |||
| e9f12ae30a | |||
| 2f977aae18 | |||
| 0e5a862d8a | |||
| 1e46cd255b | |||
| e5e6af41a6 | |||
| ce437eb8d2 | |||
| 4c019c55d2 | |||
| ae440a92ac | |||
| 54d2e8bfdd | |||
| 3f206981d9 | |||
| fa7407cd42 | |||
| 866b9524b3 | |||
| d1cde4d0a7 | |||
| b01e7e3362 | |||
| e9b020beaa | |||
| 2fcd38c2bc | |||
| 300b34e268 | |||
| ce0e87373d | |||
| 7e1c6a5819 | |||
| 613214cdca | |||
| 009f53a267 | |||
| f3ad922a8f | |||
| 7b27a8e993 | |||
| fcb7072fee | |||
| 7ab1792ef7 | |||
| 40d305b35d | |||
| 2d7e91ba8a | |||
| b05434bc6f | |||
| 7b4c044480 | |||
| c14eb4e54a | |||
| f6c8f46462 | |||
| faf9ed9fec | |||
| 930ce4af60 | |||
| d51a986dd4 | |||
| 02845f546e | |||
| fff34a7f0f | |||
| 21dd715b42 | |||
| d9a693019b | |||
| 607d2486ea | |||
| 77f58326af | |||
| bf14cbdb27 | |||
| 93db420f80 | |||
| a209d0d7fa | |||
| f564a72d03 | |||
| aeb01bd216 | |||
| bc4d73da02 | |||
| f9e996e006 | |||
| 4dbc546e7b | |||
| 9a1a7dd531 | |||
| 7ac96f7526 | |||
| f613901eac | |||
| 4cd5624fa7 | |||
| fc6891a0e3 | |||
| fb7ccbd7b4 | |||
| 17c399d4e8 | |||
| dd19622823 | |||
| 46fa6e47fe | |||
| 7fa42cfaad | |||
| 5d8640109d | |||
| 6f6b23e879 | |||
| d2116a187e | |||
| f58652e51c | |||
| bf53035e3f | |||
| 60c6bb9865 | |||
| 67b71c0f89 | |||
| 5766fb1f31 | |||
| dbd69536ed | |||
| 08f0047529 | |||
| 54a38aa927 | |||
| 173cc13d01 | |||
| 1899f399b6 | |||
| 4c5921a7a4 | |||
| be84dd73a9 | |||
| 9f3f07f3ae | |||
| d260ccfc96 | |||
| 1c3b9754aa | |||
| 37c26b77ee | |||
| ff772dd28b | |||
| 60e2928ec1 | |||
| f8e57147b0 | |||
| 1bef748dc4 | |||
| b2fa0fdf53 | |||
| ab198c0c5f | |||
| f577af452d | |||
| a7802e9377 | |||
| 3b03f9a010 | |||
| cb194e06ce | |||
| a24780fe5e | |||
| a7c28f5827 | |||
| 425821863b | |||
| 8db6555bdb | |||
| 6557bf1b20 | |||
| 6648084c64 | |||
| 5543441618 | |||
| 0508e1e638 | |||
| adf119e960 | |||
| 2bc57fbee3 | |||
| 42b06af577 | |||
| f9a69c449d | |||
| 3f9affd2ad | |||
| 23701248f3 | |||
| c9abab6828 | |||
| 9dc9378bcc | |||
| 5cc152b8dd | |||
| 9bd6d28514 | |||
| 58816e314c | |||
| e93fbc6900 | |||
| f8c2e198c5 | |||
| f69e252c7a | |||
| 96dfa9b526 | |||
| 2b24635ef7 | |||
| fde6099769 | |||
| 7b3693bb29 | |||
| df8fa74e2a | |||
| 9747ab61f9 | |||
| d7e72797a8 | |||
| 0dfd2eadc1 | |||
| 291ec1eeb2 | |||
| b24eb621ae | |||
| 0fa148e65e | |||
| 3f6b24d33a | |||
| 9fee2ebeb5 | |||
| 99828a8f15 | |||
| 2526626646 | |||
| 582913dc31 | |||
| 94c1b74a17 | |||
| cbd1b28d0d | |||
| 05ffb50037 | |||
| 72e13ddeb2 | |||
| 78f09d7645 | |||
| f69121116a | |||
| 0136215ef1 | |||
| ab534ac55d | |||
| 67bbd59924 | |||
| f0b1a587aa | |||
| ae8f858c56 | |||
| 7426eb285f | |||
| f91f2e3e6d | |||
| e39ee10105 | |||
| 2ef2f0f63b | |||
| e875c91121 | |||
| 6610abcd5f | |||
| aed9b31294 | |||
| 6597eb27c7 | |||
| 035a39a9a8 | |||
| 9c547d5eef | |||
| 504fa5ffda | |||
| ad66dbfd0b | |||
| 0adb579736 | |||
| d4c83e5dd2 | |||
| 821a8c6e65 | |||
| ef60809219 | |||
| a21ed06d27 | |||
| 97f59405aa | |||
| b586bd3b10 | |||
| c617b17037 | |||
| 73bbfcb246 | |||
| cfa7d04c49 | |||
| fb191693d1 | |||
| 743a19027a | |||
| ced539579e | |||
| 225af34ce9 | |||
| eb80b7ec34 | |||
| 3df960bb52 | |||
| 25fcde9507 | |||
| d8abe75526 | |||
| 15fe8f1c51 | |||
| ce7b55871b | |||
| 9d8fa28dd9 | |||
| 3a3e9770f3 | |||
| 2d037fa130 |
+7
-2
@@ -41,7 +41,10 @@
|
||||
/Vulkan/Vulkan-build
|
||||
/Vulkan/glslang-build
|
||||
|
||||
/wxWidgets/lib
|
||||
# Themes
|
||||
!/bin/GuiConfigs/
|
||||
/bin/GuiConfigs/*.ini
|
||||
|
||||
/bin/rpcs3.ini
|
||||
/bin/rpcs3.ipdb
|
||||
/bin/rpcs3.iobj
|
||||
@@ -56,6 +59,7 @@ rpcs3/git-version.h
|
||||
|
||||
# Visual Studio Files
|
||||
.vs/*
|
||||
*.ipch
|
||||
*.vspx
|
||||
*.psess
|
||||
*.VC.*
|
||||
@@ -71,6 +75,7 @@ rpcs3/git-version.h
|
||||
!/bin/dev_hdd0/game/
|
||||
/bin/dev_hdd0/game/*
|
||||
!/bin/dev_hdd0/game/TEST12345/
|
||||
/bin/dev_hdd0/disc/*
|
||||
|
||||
# Ignore other system generated files
|
||||
bin/dev_hdd0/*.txt
|
||||
@@ -92,4 +97,4 @@ rpcs3/rpcs3_*_cotire.cmake
|
||||
moc_*.cpp
|
||||
qrc_resources.cpp
|
||||
rpcs3_automoc.cpp
|
||||
ui_*.h
|
||||
ui_*.h
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
[submodule "llvm"]
|
||||
path = llvm
|
||||
url = https://github.com/llvm-mirror/llvm
|
||||
branch = release_40
|
||||
branch = release_50
|
||||
[submodule "rsx_program_decompiler"]
|
||||
path = rsx_program_decompiler
|
||||
url = https://github.com/RPCS3/rsx_program_decompiler
|
||||
@@ -17,7 +17,7 @@
|
||||
url = https://github.com/Microsoft/GSL.git
|
||||
[submodule "libpng"]
|
||||
path = 3rdparty/libpng
|
||||
url = https://github.com/RPCS3/libpng
|
||||
url = https://github.com/Zangetsu38/libpng
|
||||
ignore = dirty
|
||||
[submodule "Vulkan/glslang"]
|
||||
path = Vulkan/glslang
|
||||
@@ -42,5 +42,5 @@
|
||||
url = https://github.com/madler/zlib
|
||||
[submodule "3rdparty/hidapi"]
|
||||
path = 3rdparty/hidapi
|
||||
url = https://github.com/RPCS3/hidapi
|
||||
url = https://github.com/Zangetsu38/hidapi
|
||||
branch = master
|
||||
+35
-23
@@ -29,10 +29,6 @@ matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
include:
|
||||
- os: linux
|
||||
compiler: clang
|
||||
env: WITHOUT_LLVM="yes"
|
||||
|
||||
|
||||
git:
|
||||
@@ -47,51 +43,65 @@ before_install:
|
||||
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
|
||||
sudo add-apt-repository ppa:beineri/opt-qt59-trusty -y;
|
||||
sudo apt-get update;
|
||||
sudo apt-get install qt59base -y --allow-unauthenticated;
|
||||
wget http://download.qt.io/official_releases/online_installers/qt-unified-linux-x64-online.run ;
|
||||
chmod a+x ./qt-unified-linux-x64-online.run ;
|
||||
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/libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_amd64.deb;
|
||||
wget http://mirrors.kernel.org/ubuntu/pool/universe/v/vulkan/libvulkan1_1.0.21.0+dfsg1-1~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.21.0+dfsg1-1~16.04.1_amd64.deb libvulkan-dev_1.0.21.0+dfsg1-1~16.04.1_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 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
|
||||
- source /opt/qt59/bin/qt59-env.sh
|
||||
- mkdir build
|
||||
- cd build
|
||||
- if [ -z "$WITHOUT_LLVM" ]; then
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr;
|
||||
- export CMAKE_PREFIX_PATH=~/Qt/5.9.1/gcc_64/lib/cmake
|
||||
- if [ "$TRAVIS_PULL_REQUEST" = false ]; then
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH";
|
||||
else
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DWITHOUT_LLVM=ON;
|
||||
export CXXFLAGS="$CXXFLAGS -DBRANCH=$TRAVIS_REPO_SLUG/$TRAVIS_BRANCH/#$TRAVIS_PULL_REQUEST";
|
||||
fi;
|
||||
- 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=${PWD}/3rdparty/libpng:/opt/qt59/lib/:$LD_LIBRARY_PATH ;
|
||||
export LD_LIBRARY_PATH=~/Qt/5.9.1/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 ;
|
||||
unset QTDIR; unset QT_PLUGIN_PATH ;
|
||||
export PATH=~/Qt/5.9.1/gcc_64/bin/:${PATH} ;
|
||||
./linuxdeployqt*.AppImage --appimage-extract ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -bundle-non-qt-libs ;
|
||||
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -appimage ;
|
||||
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/ ;
|
||||
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 ;
|
||||
zip -r9 rpcs3.zip ./RPCS3*.AppImage;
|
||||
if [ -z "$WITHOUT_LLVM" ]; then
|
||||
export LLVM="-LLVM";
|
||||
fi;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}${LLVM}_linux64 --upload-file rpcs3.zip;
|
||||
curl ${UPLOAD_URL}${TRAVIS_COMMIT:0:7}-${TRAVIS_BUILD_NUMBER}_linux64 --upload-file ./RPCS3*.AppImage;
|
||||
fi;
|
||||
|
||||
script:
|
||||
@@ -124,9 +134,11 @@ addons:
|
||||
- libstdc++-5-dev
|
||||
- lib32stdc++6
|
||||
- zlib1g-dev
|
||||
# We need to install qt 5.8 manually because the version trusty provides is too old.
|
||||
# We need to install qt 5.9.1 manually because the version trusty provides is too old.
|
||||
#- qtbase5-dev
|
||||
- libudev-dev
|
||||
- libevdev-dev
|
||||
- libpulse-dev
|
||||
coverity_scan:
|
||||
project:
|
||||
name: $TRAVIS_REPO_SLUG
|
||||
|
||||
Vendored
+1
-1
Submodule 3rdparty/ffmpeg updated: 8dd84dc1ea...7b7ae7b067
Vendored
+1
-1
Submodule 3rdparty/hidapi updated: c095a22c53...4c2750112e
Vendored
+1
-1
Submodule 3rdparty/libpng updated: 1dcba4d6eb...bbbcaf1122
+1
-1
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
cmake_minimum_required(VERSION 3.0.2)
|
||||
|
||||
option(WITH_GDB "WITH_GDB" OFF)
|
||||
option(WITHOUT_LLVM "WITHOUT_LLVM" OFF)
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
# Getting Started
|
||||
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](http://www.emunewz.net/forum/forumdisplay.php?fid=172).
|
||||
Before getting started using the emulator, read the [Quickstart Guide](https://rpcs3.net/quickstart) and the [FAQ](https://rpcs3.net/faq). After reading those, if you need support, visit our [Forums](https://forums.rpcs3.net).
|
||||
|
||||
# Issue Reporting
|
||||
|
||||
@@ -13,7 +13,7 @@ Before getting started using the emulator, read the [Quickstart Guide](https://r
|
||||
- Use understandable English. It doesn't need to be perfect, but clear enough to understand your message.
|
||||
- While reporting issues, don't forget to include details about your system (OS, CPU, GPU, etc.), as well as the RPCS3.log file.
|
||||
|
||||
Submitting your test results for Commercial Games must be done on our forums' [Commercial Games](http://www.emunewz.net/forum/forumdisplay.php?fid=193) section. If there's already a thread for the game you want to report post in it, otherwise please make a new thread following the [Guidelines for submitting new games](http://www.emunewz.net/forum/showthread.php?tid=174376).
|
||||
Submitting your test results for Commercial Games must be done on our forums. Please read the [Game Compatibility](https://github.com/RPCS3/rpcs3/wiki/Game-Compatibility) wiki page before doing so.
|
||||
|
||||
# Contributing
|
||||
|
||||
|
||||
@@ -8,9 +8,9 @@ RPCS3
|
||||
The world's first open-source PlayStation 3 emulator/debugger written in C++ for Windows and Linux.
|
||||
|
||||
You can find some basic information in our [**website**](https://rpcs3.net/).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](http://www.emunewz.net/forum/forumdisplay.php?fid=172) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
For discussion about this emulator and PS3 emulation please visit our [**forums**](https://forums.rpcs3.net) and our [**Discord server**](https://discord.me/RPCS3).
|
||||
|
||||
[**Support Lead Developer Nekotekina on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
[**Support Lead Developers Nekotekina and kd-11 on Patreon**](https://www.patreon.com/Nekotekina)
|
||||
|
||||
|
||||
## Development
|
||||
@@ -21,24 +21,24 @@ If you want to contribute please take a look at the [Coding Style](https://githu
|
||||
## Dependencies
|
||||
|
||||
### Windows
|
||||
* [Visual Studio 2015](https://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2015](http://www.microsoft.com/en-us/download/details.aspx?id=48145)
|
||||
* [Visual Studio 2017](https://www.visualstudio.com/downloads/)
|
||||
* [Visual C++ Redistributable Packages for Visual Studio 2017](https://go.microsoft.com/fwlink/?LinkId=746572)
|
||||
* [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.7+](https://www.qt.io/download-open-source/) (required; add QTDIR `<QtInstallFolder>\5.7\msvc2015_64\` environment variable if you do not want to use the Visual Studio Qt Plugin)
|
||||
* [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)
|
||||
* [Visual Studio Qt Plugin](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2015) (optional; see above)
|
||||
|
||||
### Linux
|
||||
* [Qt 5.7+](https://www.qt.io/download-open-source/)
|
||||
* [Qt 5.9+](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 libGLEW`
|
||||
* Fedora: `sudo dnf install cmake qt5-devel vulkan-devel glew glew-devel`
|
||||
|
||||
### Mac OSX
|
||||
Mac OSX 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`
|
||||
* Install with Homebrew: `brew install glew llvm qt cmake`
|
||||
|
||||
|
||||
## Building on Windows:
|
||||
@@ -47,10 +47,10 @@ 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.7\msvc2015_64\` </br>
|
||||
1) Add `QTDIR` environment variable and set it to `<QtInstallFolder>\5.9\msvc2017_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.7\msvc2015_64`. </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>
|
||||
2) While selecting the rpcs3qt project, go to Qt5->Project Setting and select the version you added.
|
||||
|
||||
### Building the projects
|
||||
@@ -66,7 +66,10 @@ To initialize the repository don't forget to execute `git submodule update --ini
|
||||
4) `cmake CMakeLists.txt && make GitVersion && make` </br>
|
||||
5) Run RPCS3 with `./bin/rpcs3` </br>
|
||||
|
||||
If you are on OSX and want to build with llvm don't forget to add `-DLLVM_DIR=...` (or wherever llvm brew was installed) to cmake invocation.
|
||||
If you are on OSX 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).
|
||||
|
||||
When using GDB, configure it to ignore SIGSEGV signal (`handle SIGSEGV nostop noprint`).
|
||||
|
||||
|
||||
+25
-3
@@ -48,6 +48,11 @@ namespace cfg
|
||||
static void decode(const YAML::Node& data, class _base& rhs);
|
||||
}
|
||||
|
||||
std::vector<std::string> cfg::make_int_range(s64 min, s64 max)
|
||||
{
|
||||
return {std::to_string(min), std::to_string(max)};
|
||||
}
|
||||
|
||||
bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
{
|
||||
// TODO: this could be rewritten without exceptions (but it should be as safe as possible and provide logs)
|
||||
@@ -82,6 +87,8 @@ bool cfg::try_to_int64(s64* out, const std::string& value, s64 min, s64 max)
|
||||
|
||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, const std::string& value)
|
||||
{
|
||||
u64 max = -1;
|
||||
|
||||
for (u64 i = 0;; i++)
|
||||
{
|
||||
std::string var;
|
||||
@@ -99,6 +106,8 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
max = i;
|
||||
}
|
||||
|
||||
try
|
||||
@@ -108,14 +117,22 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||
|
||||
if (pos != value.size())
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): unexpected characters (pos=%zu)", value, pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (val > max)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): out of bounds(0..%u)", value, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (out) *out = val;
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
if (out) cfg.error("cfg::try_to_enum_value('%s'): invalid enum value: %s", value, e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -268,14 +285,19 @@ std::string cfg::node::to_string() const
|
||||
YAML::Emitter out;
|
||||
cfg::encode(out, *this);
|
||||
|
||||
return{ out.c_str(), out.size() };
|
||||
return {out.c_str(), out.size()};
|
||||
}
|
||||
|
||||
bool cfg::node::from_string(const std::string& value)
|
||||
bool cfg::node::from_string(const std::string& value) try
|
||||
{
|
||||
cfg::decode(YAML::Load(value), *this);
|
||||
return true;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cfg.fatal("%s thrown: %s", typeid(e).name(), e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
void cfg::node::from_default()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
// Format min and max values
|
||||
std::vector<std::string> make_int_range(s64 min, s64 max);
|
||||
|
||||
// Convert string to signed integer
|
||||
bool try_to_int64(s64* out, const std::string& value, s64 min, s64 max);
|
||||
|
||||
@@ -249,6 +252,11 @@ namespace cfg
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> to_list() const override
|
||||
{
|
||||
return make_int_range(Min, Max);
|
||||
}
|
||||
};
|
||||
|
||||
// Alias for 32 bit int
|
||||
|
||||
+66
-6
@@ -93,6 +93,7 @@ static fs::error to_error(DWORD e)
|
||||
case ERROR_NEGATIVE_SEEK: return fs::error::inval;
|
||||
case ERROR_DIRECTORY: return fs::error::inval;
|
||||
case ERROR_INVALID_NAME: return fs::error::inval;
|
||||
case ERROR_SHARING_VIOLATION: return fs::error::acces;
|
||||
default: fmt::throw_exception("Unknown Win32 error: %u.", e);
|
||||
}
|
||||
}
|
||||
@@ -509,7 +510,7 @@ bool fs::remove_dir(const std::string& path)
|
||||
#endif
|
||||
}
|
||||
|
||||
bool fs::rename(const std::string& from, const std::string& to)
|
||||
bool fs::rename(const std::string& from, const std::string& to, bool overwrite)
|
||||
{
|
||||
const auto device = get_virtual_device(from);
|
||||
|
||||
@@ -524,14 +525,43 @@ bool fs::rename(const std::string& from, const std::string& to)
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get()))
|
||||
const auto ws1 = to_wchar(from);
|
||||
const auto ws2 = to_wchar(to);
|
||||
|
||||
if (!MoveFileExW(ws1.get(), ws2.get(), overwrite ? MOVEFILE_REPLACE_EXISTING : 0))
|
||||
{
|
||||
g_tls_error = to_error(GetLastError());
|
||||
DWORD error1 = GetLastError();
|
||||
|
||||
if (overwrite && error1 == ERROR_ACCESS_DENIED && is_dir(from) && is_dir(to))
|
||||
{
|
||||
if (RemoveDirectoryW(ws2.get()))
|
||||
{
|
||||
if (MoveFileW(ws1.get(), ws2.get()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
error1 = GetLastError();
|
||||
CreateDirectoryW(ws2.get(), NULL); // TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
error1 = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
g_tls_error = to_error(error1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
if (!overwrite && exists(to))
|
||||
{
|
||||
g_tls_error = fs::error::exist;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (::rename(from.c_str(), to.c_str()) != 0)
|
||||
{
|
||||
g_tls_error = to_error(errno);
|
||||
@@ -764,7 +794,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
|
||||
}
|
||||
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
DWORD share = FILE_SHARE_READ;
|
||||
if (!test(mode & fs::unshare))
|
||||
{
|
||||
share |= FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||
}
|
||||
|
||||
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -772,7 +808,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class windows_file final : public file_base
|
||||
class windows_file final : public file_base, public get_native_handle
|
||||
{
|
||||
const HANDLE m_handle;
|
||||
|
||||
@@ -879,6 +915,11 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return size.QuadPart;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_handle;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<windows_file>(handle);
|
||||
@@ -902,7 +943,7 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
return;
|
||||
}
|
||||
|
||||
class unix_file final : public file_base
|
||||
class unix_file final : public file_base, public get_native_handle
|
||||
{
|
||||
const int m_fd;
|
||||
|
||||
@@ -991,6 +1032,11 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
|
||||
|
||||
return file_info.st_size;
|
||||
}
|
||||
|
||||
native_handle get() override
|
||||
{
|
||||
return m_fd;
|
||||
}
|
||||
};
|
||||
|
||||
m_file = std::make_unique<unix_file>(fd);
|
||||
@@ -1066,6 +1112,20 @@ fs::file::file(const void* ptr, std::size_t size)
|
||||
m_file = std::make_unique<memory_stream>(ptr, size);
|
||||
}
|
||||
|
||||
fs::native_handle fs::file::get_handle() const
|
||||
{
|
||||
if (auto getter = dynamic_cast<get_native_handle*>(m_file.get()))
|
||||
{
|
||||
return getter->get();
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
return INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void fs::dir::xnull() const
|
||||
{
|
||||
fmt::throw_exception<std::logic_error>("fs::dir is null");
|
||||
|
||||
+18
-1
@@ -10,6 +10,12 @@
|
||||
|
||||
namespace fs
|
||||
{
|
||||
#ifdef _WIN32
|
||||
using native_handle = void*;
|
||||
#else
|
||||
using native_handle = int;
|
||||
#endif
|
||||
|
||||
// File open mode flags
|
||||
enum class open_mode : u32
|
||||
{
|
||||
@@ -19,6 +25,7 @@ namespace fs
|
||||
create,
|
||||
trunc,
|
||||
excl,
|
||||
unshare,
|
||||
|
||||
__bitset_enum_max
|
||||
};
|
||||
@@ -29,6 +36,7 @@ namespace fs
|
||||
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
|
||||
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
|
||||
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
|
||||
constexpr auto unshare = +open_mode::unshare; // Prevent opening the file twice
|
||||
|
||||
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;
|
||||
|
||||
@@ -55,6 +63,12 @@ namespace fs
|
||||
s64 ctime;
|
||||
};
|
||||
|
||||
// Native handle getter
|
||||
struct get_native_handle
|
||||
{
|
||||
virtual native_handle get() = 0;
|
||||
};
|
||||
|
||||
// File handle base
|
||||
struct file_base
|
||||
{
|
||||
@@ -145,7 +159,7 @@ namespace fs
|
||||
bool create_path(const std::string& path);
|
||||
|
||||
// Rename (move) file or directory
|
||||
bool rename(const std::string& from, const std::string& to);
|
||||
bool rename(const std::string& from, const std::string& to, bool overwrite);
|
||||
|
||||
// Copy file contents
|
||||
bool copy_file(const std::string& from, const std::string& to, bool overwrite);
|
||||
@@ -347,6 +361,9 @@ namespace fs
|
||||
if (seek(0), !read(result)) xfail();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get native handle if available
|
||||
native_handle get_handle() const;
|
||||
};
|
||||
|
||||
class dir final
|
||||
|
||||
+42
-14
@@ -12,6 +12,7 @@
|
||||
#include "File.h"
|
||||
#include "Log.h"
|
||||
#include "mutex.h"
|
||||
#include "sysinfo.h"
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -89,13 +90,13 @@ extern void jit_finalize()
|
||||
// Helper class
|
||||
struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
{
|
||||
std::unordered_map<std::string, std::uintptr_t>& m_link;
|
||||
std::unordered_map<std::string, u64>& m_link;
|
||||
|
||||
std::array<u8, 16>* m_tramps{};
|
||||
|
||||
u8* m_code_addr{}; // TODO
|
||||
|
||||
MemoryManager(std::unordered_map<std::string, std::uintptr_t>& table)
|
||||
MemoryManager(std::unordered_map<std::string, u64>& table)
|
||||
: m_link(table)
|
||||
{
|
||||
}
|
||||
@@ -257,11 +258,11 @@ struct MemoryManager : llvm::RTDyldMemoryManager
|
||||
return RTDyldMemoryManager::registerEHFrames(addr, load_addr, size);
|
||||
}
|
||||
|
||||
virtual void deregisterEHFrames(u8* addr, u64 load_addr, std::size_t size) override
|
||||
virtual void deregisterEHFrames() override
|
||||
{
|
||||
LOG_ERROR(GENERAL, "deregisterEHFrames() called"); // Not expected
|
||||
|
||||
return RTDyldMemoryManager::deregisterEHFrames(addr, load_addr, size);
|
||||
return RTDyldMemoryManager::deregisterEHFrames();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -343,32 +344,54 @@ public:
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Created module: %s", module->getName().data());
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
static std::unique_ptr<llvm::MemoryBuffer> load(const std::string& path)
|
||||
{
|
||||
std::string name = m_path;
|
||||
name.append(module->getName());
|
||||
|
||||
if (fs::file cached{name, fs::read})
|
||||
if (fs::file cached{path, fs::read})
|
||||
{
|
||||
auto buf = llvm::MemoryBuffer::getNewUninitMemBuffer(cached.size());
|
||||
cached.read(const_cast<char*>(buf->getBufferStart()), buf->getBufferSize());
|
||||
return buf;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* module) override
|
||||
{
|
||||
std::string path = m_path;
|
||||
path.append(module->getName());
|
||||
|
||||
if (auto buf = load(path))
|
||||
{
|
||||
LOG_SUCCESS(GENERAL, "LLVM: Loaded module: %s", module->getName().data());
|
||||
return buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, std::uintptr_t>& _link, std::string _cpu)
|
||||
jit_compiler::jit_compiler(const std::unordered_map<std::string, u64>& _link, std::string _cpu)
|
||||
: m_link(std::move(_link))
|
||||
, m_cpu(std::move(_cpu))
|
||||
{
|
||||
if (m_cpu.empty())
|
||||
{
|
||||
m_cpu = llvm::sys::getHostCPUName();
|
||||
|
||||
if (m_cpu == "sandybridge" ||
|
||||
m_cpu == "ivybridge" ||
|
||||
m_cpu == "haswell" ||
|
||||
m_cpu == "broadwell" ||
|
||||
m_cpu == "skylake" ||
|
||||
m_cpu == "skylake-avx512" ||
|
||||
m_cpu == "cannonlake")
|
||||
{
|
||||
if (!utils::has_avx())
|
||||
{
|
||||
m_cpu = "nehalem";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result;
|
||||
@@ -430,6 +453,11 @@ void jit_compiler::add(std::unique_ptr<llvm::Module> module, const std::string&
|
||||
}
|
||||
}
|
||||
|
||||
void jit_compiler::add(const std::string& path)
|
||||
{
|
||||
m_engine->addObjectFile(std::move(llvm::object::ObjectFile::createObjectFile(*ObjectCache::load(path)).get()));
|
||||
}
|
||||
|
||||
void jit_compiler::fin()
|
||||
{
|
||||
m_engine->finalizeObject();
|
||||
|
||||
+4
-1
@@ -49,9 +49,12 @@ public:
|
||||
return m_context;
|
||||
}
|
||||
|
||||
// Add module
|
||||
// Add module (path to obj cache dir)
|
||||
void add(std::unique_ptr<llvm::Module> module, const std::string& path);
|
||||
|
||||
// Add object (path to obj file)
|
||||
void add(const std::string& path);
|
||||
|
||||
// Finalize
|
||||
void fin();
|
||||
|
||||
|
||||
+175
-18
@@ -3,16 +3,21 @@
|
||||
#include "StrFmt.h"
|
||||
#include "sema.h"
|
||||
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "rpcs3_version.h"
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef _WIN32
|
||||
#define NOMINMAX
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <chrono>
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
static std::string empty_string()
|
||||
{
|
||||
return {};
|
||||
@@ -44,29 +49,38 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
|
||||
|
||||
namespace logs
|
||||
{
|
||||
constexpr std::size_t s_log_size = 128 * 1024 * 1024;
|
||||
constexpr std::size_t s_log_size_s = s_log_size / 2;
|
||||
constexpr std::size_t s_log_size_t = s_log_size / 4 + s_log_size_s;
|
||||
constexpr std::size_t s_log_size_e = s_log_size / 8 + s_log_size_t;
|
||||
constexpr std::size_t s_log_size_f = s_log_size / 16 + s_log_size_e;
|
||||
|
||||
class file_writer
|
||||
{
|
||||
// Could be memory-mapped file
|
||||
fs::file m_file;
|
||||
std::string m_name;
|
||||
|
||||
#ifdef _WIN32
|
||||
::HANDLE m_fmap;
|
||||
#endif
|
||||
atomic_t<std::size_t> m_pos{0};
|
||||
std::size_t m_size{0};
|
||||
uchar* m_fptr{};
|
||||
|
||||
public:
|
||||
file_writer(const std::string& name);
|
||||
|
||||
virtual ~file_writer() = default;
|
||||
virtual ~file_writer();
|
||||
|
||||
// Append raw data
|
||||
void log(const char* text, std::size_t size);
|
||||
void log(logs::level sev, const char* text, std::size_t size);
|
||||
};
|
||||
|
||||
struct file_listener : public file_writer, public listener
|
||||
{
|
||||
file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
{
|
||||
const std::string& start = fmt::format("\xEF\xBB\xBF" "RPCS3 v%s\n", rpcs3::version.to_string());
|
||||
file_writer::log(start.data(), start.size());
|
||||
}
|
||||
file_listener(const std::string& name);
|
||||
|
||||
virtual ~file_listener() = default;
|
||||
|
||||
// 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;
|
||||
@@ -137,12 +151,26 @@ namespace logs
|
||||
}
|
||||
};
|
||||
|
||||
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};
|
||||
|
||||
void reset()
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
@@ -159,6 +187,17 @@ namespace logs
|
||||
|
||||
g_channels[ch_name].set_level(value);
|
||||
}
|
||||
|
||||
// Must be called in main() to stop accumulating messages in g_messages
|
||||
void set_init()
|
||||
{
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
g_messages.clear();
|
||||
g_init = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logs::listener::~listener()
|
||||
@@ -170,11 +209,19 @@ void logs::listener::add(logs::listener* _new)
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
// Install new listener at the end of linked list
|
||||
while (lis->m_next || !lis->m_next.compare_and_swap_test(nullptr, _new))
|
||||
{
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Send initial messages
|
||||
for (const auto& msg : g_messages)
|
||||
{
|
||||
_new->log(msg.stamp, msg.m, msg.prefix, msg.text);
|
||||
}
|
||||
}
|
||||
|
||||
void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u64* args)
|
||||
@@ -207,12 +254,29 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, const u
|
||||
}
|
||||
|
||||
// Get text
|
||||
std::string text;
|
||||
thread_local std::string text; text.clear();
|
||||
fmt::raw_append(text, fmt, sup, args);
|
||||
std::string prefix = g_tls_log_prefix();
|
||||
|
||||
// Get first (main) listener
|
||||
listener* lis = get_logger();
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
semaphore_lock lock(g_mutex);
|
||||
|
||||
if (!g_init)
|
||||
{
|
||||
while (lis)
|
||||
{
|
||||
lis->log(stamp, *this, prefix, text);
|
||||
lis = lis->m_next;
|
||||
}
|
||||
|
||||
// Store message additionally
|
||||
g_messages.emplace_back(stored_message{*this, stamp, std::move(prefix), text});
|
||||
}
|
||||
}
|
||||
|
||||
// Send message to all listeners
|
||||
while (lis)
|
||||
@@ -225,13 +289,28 @@ 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)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!m_file.open(fs::get_config_dir() + name, fs::rewrite + fs::append))
|
||||
if (!m_file.open(m_name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
|
||||
{
|
||||
fmt::throw_exception("Can't create log file %s (error %s)", name, fs::g_tls_error);
|
||||
fmt::throw_exception("Can't create file %s (error %s)", name, fs::g_tls_error);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
m_fmap = CreateFileMappingW(m_file.get_handle(), 0, PAGE_READWRITE, s_log_size >> 32, s_log_size & 0xffffffff, 0);
|
||||
m_fptr = m_fmap ? (uchar*)MapViewOfFile(m_fmap, FILE_MAP_WRITE, 0, 0, 0) : nullptr;
|
||||
#else
|
||||
m_file.trunc(s_log_size);
|
||||
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;
|
||||
std::memset(m_fptr, '\n', s_log_size);
|
||||
|
||||
// Rotate backups (TODO)
|
||||
fs::rename(m_name + ".gz", m_name + "1.gz", true);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
@@ -239,14 +318,92 @@ logs::file_writer::file_writer(const std::string& name)
|
||||
}
|
||||
}
|
||||
|
||||
void logs::file_writer::log(const char* text, std::size_t size)
|
||||
logs::file_writer::~file_writer()
|
||||
{
|
||||
m_file.write(text, size);
|
||||
if (m_size == 0)
|
||||
{
|
||||
m_size = std::min<std::size_t>(+m_pos, s_log_size);
|
||||
}
|
||||
|
||||
// Compress
|
||||
z_stream zs{};
|
||||
if (deflateInit2(&zs, 9, Z_DEFLATED, 16 + 15, 9, Z_DEFAULT_STRATEGY) == Z_OK)
|
||||
{
|
||||
auto buf = std::make_unique<uchar[]>(s_log_size);
|
||||
zs.avail_in = ::narrow<u32>(m_size);
|
||||
zs.avail_out = s_log_size;
|
||||
zs.next_in = m_fptr;
|
||||
zs.next_out = buf.get();
|
||||
|
||||
if (deflate(&zs, Z_FINISH) != Z_STREAM_ERROR)
|
||||
{
|
||||
fs::file(m_name + ".gz", fs::rewrite).write(buf.get(), zs.total_out);
|
||||
}
|
||||
|
||||
if (deflateEnd(&zs) != Z_OK)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
}
|
||||
|
||||
void logs::file_writer::log(logs::level sev, const char* text, std::size_t size)
|
||||
{
|
||||
// Adaptive log limit
|
||||
const auto lim =
|
||||
sev >= logs::level::success ? s_log_size_s :
|
||||
sev == logs::level::todo ? s_log_size_t :
|
||||
sev == logs::level::error ? s_log_size_e : s_log_size_f;
|
||||
|
||||
if (m_pos >= lim)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Acquire memory
|
||||
const auto pos = m_pos.fetch_add(size);
|
||||
|
||||
// Write if possible
|
||||
if (pos + size <= s_log_size)
|
||||
{
|
||||
std::memcpy(m_fptr + pos, text, size);
|
||||
}
|
||||
else if (pos <= s_log_size)
|
||||
{
|
||||
m_size = pos;
|
||||
}
|
||||
}
|
||||
|
||||
logs::file_listener::file_listener(const std::string& name)
|
||||
: file_writer(name)
|
||||
, listener()
|
||||
{
|
||||
// Write UTF-8 BOM
|
||||
file_writer::log(logs::level::always, "\xEF\xBB\xBF", 3);
|
||||
|
||||
// Write initial message
|
||||
stored_message ver;
|
||||
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());
|
||||
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));
|
||||
}
|
||||
|
||||
void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::string& prefix, const std::string& _text)
|
||||
{
|
||||
std::string text; text.reserve(prefix.size() + _text.size() + 200);
|
||||
thread_local std::string text;
|
||||
|
||||
// Used character: U+00B7 (Middle Dot)
|
||||
switch (msg.sev)
|
||||
@@ -275,7 +432,7 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
text += "} ";
|
||||
}
|
||||
|
||||
if ('\0' != *msg.ch->name)
|
||||
if (msg.ch && '\0' != *msg.ch->name)
|
||||
{
|
||||
text += msg.ch->name;
|
||||
text += msg.sev == level::todo ? " TODO: " : ": ";
|
||||
@@ -288,5 +445,5 @@ void logs::file_listener::log(u64 stamp, const logs::message& msg, const std::st
|
||||
text += _text;
|
||||
text += '\n';
|
||||
|
||||
file_writer::log(text.data(), text.size());
|
||||
file_writer::log(msg.sev, text.data(), text.size());
|
||||
}
|
||||
|
||||
@@ -257,8 +257,8 @@ struct fmt::cfmt_src
|
||||
|
||||
void skip(std::size_t extra)
|
||||
{
|
||||
++sup += extra;
|
||||
++args += extra;
|
||||
sup += extra + 1;
|
||||
args += extra + 1;
|
||||
}
|
||||
|
||||
std::size_t fmt_string(std::string& out, std::size_t extra) const
|
||||
|
||||
+16
-11
@@ -30,13 +30,25 @@ thread_local u64 g_tls_fault_spu = 0;
|
||||
|
||||
static void report_fatal_error(const std::string& msg)
|
||||
{
|
||||
static semaphore<> g_report_only_once;
|
||||
|
||||
g_report_only_once.wait();
|
||||
|
||||
std::string _msg = msg + "\n"
|
||||
"HOW TO REPORT ERRORS: Check the FAQ, README, other sources.\n"
|
||||
"HOW TO REPORT ERRORS: https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support\n"
|
||||
"Please, don't send incorrect reports. Thanks for understanding.\n";
|
||||
|
||||
#ifdef _WIN32
|
||||
_msg += "Press (Ctrl+C) to copy this message.";
|
||||
MessageBoxA(0, _msg.c_str(), "Fatal error", MB_ICONERROR); // TODO: unicode message
|
||||
_msg += "\nPress Yes or Enter to visit the URL above immediately.";
|
||||
const std::size_t buf_size = _msg.size() + 1;
|
||||
const int size = static_cast<int>(buf_size);
|
||||
std::unique_ptr<wchar_t[]> buffer(new wchar_t[buf_size]);
|
||||
MultiByteToWideChar(CP_UTF8, 0, _msg.c_str(), size, buffer.get(), size);
|
||||
|
||||
if (MessageBoxW(0, buffer.get(), L"Fatal error", MB_ICONERROR | MB_YESNO) == IDYES)
|
||||
{
|
||||
ShellExecuteW(0, L"open", L"https://github.com/RPCS3/rpcs3/wiki/How-to-ask-for-Support", 0, 0, SW_SHOWNORMAL);
|
||||
}
|
||||
#else
|
||||
std::printf("Fatal error: \n%s", _msg.c_str());
|
||||
#endif
|
||||
@@ -1236,7 +1248,7 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size)))
|
||||
if (vm::check_addr(addr, std::max<std::size_t>(1, d_size), vm::page_allocated | (is_writing ? vm::page_writable : vm::page_readable)))
|
||||
{
|
||||
if (cpu)
|
||||
{
|
||||
@@ -1413,13 +1425,6 @@ static LONG exception_filter(PEXCEPTION_POINTERS pExp)
|
||||
|
||||
msg += fmt::format("RPCS3 image base: %p.\n", GetModuleHandle(NULL));
|
||||
|
||||
if (pExp->ExceptionRecord->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
|
||||
{
|
||||
msg += "\n"
|
||||
"Illegal instruction exception occured.\n"
|
||||
"Note that your CPU must support SSSE3 extension.\n";
|
||||
}
|
||||
|
||||
// TODO: print registers and the callstack
|
||||
|
||||
// Report fatal error
|
||||
|
||||
+35
-4
@@ -14,9 +14,13 @@ void fmt_class_string<patch_type>::format(std::string& out, u64 arg)
|
||||
case patch_type::le16: return "le16";
|
||||
case patch_type::le32: return "le32";
|
||||
case patch_type::le64: return "le64";
|
||||
case patch_type::bef32: return "bef32";
|
||||
case patch_type::bef64: return "bef64";
|
||||
case patch_type::be16: return "be16";
|
||||
case patch_type::be32: return "be32";
|
||||
case patch_type::be64: return "be64";
|
||||
case patch_type::lef32: return "lef32";
|
||||
case patch_type::lef64: return "lef64";
|
||||
}
|
||||
|
||||
return unknown;
|
||||
@@ -39,23 +43,44 @@ void patch_engine::append(const std::string& patch)
|
||||
u64 type64 = 0;
|
||||
cfg::try_to_enum_value(&type64, &fmt_class_string<patch_type>::format, patch[0].Scalar());
|
||||
|
||||
struct patch info;
|
||||
struct patch info{};
|
||||
info.type = static_cast<patch_type>(type64);
|
||||
info.offset = patch[1].as<u32>();
|
||||
info.value = patch[2].as<u64>();
|
||||
|
||||
switch (info.type)
|
||||
{
|
||||
case patch_type::bef32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
info.value_as<f32>() = patch[2].as<f32>();
|
||||
break;
|
||||
}
|
||||
case patch_type::bef64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
info.value_as<f64>() = patch[2].as<f64>();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
info.value = patch[2].as<u64>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
data.emplace_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
std::size_t patch_engine::apply(const std::string& name, u8* dst) const
|
||||
{
|
||||
const auto found = m_map.find(name);
|
||||
|
||||
if (found == m_map.cend())
|
||||
{
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Apply modifications sequentially
|
||||
@@ -76,11 +101,13 @@ void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::le32:
|
||||
case patch_type::lef32:
|
||||
{
|
||||
*reinterpret_cast<le_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::le64:
|
||||
case patch_type::lef64:
|
||||
{
|
||||
*reinterpret_cast<le_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
@@ -91,15 +118,19 @@ void patch_engine::apply(const std::string& name, u8* dst) const
|
||||
break;
|
||||
}
|
||||
case patch_type::be32:
|
||||
case patch_type::bef32:
|
||||
{
|
||||
*reinterpret_cast<be_t<u32, 1>*>(ptr) = static_cast<u32>(p.value);
|
||||
break;
|
||||
}
|
||||
case patch_type::be64:
|
||||
case patch_type::bef64:
|
||||
{
|
||||
*reinterpret_cast<be_t<u64, 1>*>(ptr) = static_cast<u64>(p.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found->second.size();
|
||||
}
|
||||
|
||||
+12
-2
@@ -11,9 +11,13 @@ enum class patch_type
|
||||
le16,
|
||||
le32,
|
||||
le64,
|
||||
lef32,
|
||||
lef64,
|
||||
be16,
|
||||
be32,
|
||||
be64,
|
||||
bef32,
|
||||
bef64,
|
||||
};
|
||||
|
||||
class patch_engine
|
||||
@@ -23,6 +27,12 @@ class patch_engine
|
||||
patch_type type;
|
||||
u32 offset;
|
||||
u64 value;
|
||||
|
||||
template <typename T>
|
||||
T& value_as()
|
||||
{
|
||||
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
|
||||
}
|
||||
};
|
||||
|
||||
// Database
|
||||
@@ -32,6 +42,6 @@ public:
|
||||
// Load from file
|
||||
void append(const std::string& path);
|
||||
|
||||
// Apply patch
|
||||
void apply(const std::string& name, u8* dst) const;
|
||||
// Apply patch (returns the number of entries applied)
|
||||
std::size_t apply(const std::string& name, u8* dst) const;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
namespace rpcs3
|
||||
{
|
||||
template<typename T>
|
||||
static size_t hash_base(T value)
|
||||
{
|
||||
return static_cast<size_t>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static size_t hash_struct(const T& value)
|
||||
{
|
||||
// FNV 64-bit
|
||||
size_t result = 14695981039346656037ull;
|
||||
const unsigned char *bytes = reinterpret_cast<const unsigned char*>(&value);
|
||||
|
||||
for (size_t n = 0; n < sizeof(T); ++n)
|
||||
{
|
||||
result ^= bytes[n];
|
||||
result *= 1099511628211ull;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "sysinfo.h"
|
||||
#include "StrFmt.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
std::string utils::get_system_info()
|
||||
{
|
||||
std::string result;
|
||||
std::string brand;
|
||||
|
||||
if (get_cpuid(0x80000000, 0)[0] >= 0x80000004)
|
||||
{
|
||||
for (u32 i = 0; i < 3; i++)
|
||||
{
|
||||
brand.append(reinterpret_cast<const char*>(get_cpuid(0x80000002 + i, 0).data()), 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
brand = "Unknown CPU";
|
||||
}
|
||||
|
||||
brand.erase(0, brand.find_first_not_of(' '));
|
||||
brand.erase(brand.find_last_not_of(' ') + 1);
|
||||
|
||||
while (auto found = brand.find(" ") + 1)
|
||||
{
|
||||
brand.erase(brand.begin() + found);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
::SYSTEM_INFO sysInfo;
|
||||
::GetNativeSystemInfo(&sysInfo);
|
||||
::MEMORYSTATUSEX memInfo;
|
||||
memInfo.dwLength = sizeof(memInfo);
|
||||
::GlobalMemoryStatusEx(&memInfo);
|
||||
const u32 num_proc = sysInfo.dwNumberOfProcessors;
|
||||
const u64 mem_total = memInfo.ullTotalPhys;
|
||||
#else
|
||||
const u32 num_proc = ::sysconf(_SC_NPROCESSORS_ONLN);
|
||||
const u64 mem_total = ::sysconf(_SC_PHYS_PAGES) * ::sysconf(_SC_PAGE_SIZE);
|
||||
#endif
|
||||
|
||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||
|
||||
if (has_avx())
|
||||
{
|
||||
result += " | AVX";
|
||||
}
|
||||
|
||||
if (has_rtm())
|
||||
{
|
||||
result += " | TSX";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include "types.h"
|
||||
#include <string>
|
||||
|
||||
namespace utils
|
||||
{
|
||||
inline std::array<u32, 4> get_cpuid(u32 func, u32 subfunc)
|
||||
{
|
||||
int regs[4];
|
||||
#ifdef _MSC_VER
|
||||
__cpuidex(regs, func, subfunc);
|
||||
#else
|
||||
__asm__ volatile("cpuid" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) : "a" (func), "c" (subfunc));
|
||||
#endif
|
||||
return {0u+regs[0], 0u+regs[1], 0u+regs[2], 0u+regs[3]};
|
||||
}
|
||||
|
||||
inline bool has_ssse3()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x200;
|
||||
}
|
||||
|
||||
inline bool has_avx()
|
||||
{
|
||||
return get_cpuid(0, 0)[0] >= 0x1 && get_cpuid(1, 0)[2] & 0x10000000;
|
||||
}
|
||||
|
||||
inline bool has_rtm()
|
||||
{
|
||||
// Check RTM and MPX extensions in order to filter out TSX on Haswell CPUs
|
||||
return get_cpuid(0, 0)[0] >= 0x7 && (get_cpuid(7, 0)[1] & 0x4800) == 0x4800;
|
||||
}
|
||||
|
||||
inline bool transaction_enter()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
const auto status = _xbegin();
|
||||
|
||||
if (status == _XBEGIN_STARTED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(status & _XABORT_RETRY))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string get_system_info();
|
||||
}
|
||||
+10
-4
@@ -32,7 +32,6 @@
|
||||
#define SAFE_BUFFERS
|
||||
#define NEVER_INLINE __attribute__((noinline))
|
||||
#define FORCE_INLINE __attribute__((always_inline)) inline
|
||||
#define thread_local __thread
|
||||
#endif
|
||||
|
||||
#define CHECK_SIZE(type, size) static_assert(sizeof(type) == size, "Invalid " #type " type size")
|
||||
@@ -919,7 +918,7 @@ struct error_code
|
||||
error_code() = default;
|
||||
|
||||
// Implementation must be provided specially
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg);
|
||||
static s32 error_report(const fmt_type_info* sup, u64 arg, const fmt_type_info* sup2, u64 arg2);
|
||||
|
||||
// Helper type
|
||||
enum class not_an_error : s32
|
||||
@@ -940,7 +939,7 @@ struct error_code
|
||||
|
||||
// Not an error constructor
|
||||
template<typename ET, typename = decltype(ET::__not_an_error)>
|
||||
error_code(const ET& value, int = 0)
|
||||
error_code(const ET& value, std::nullptr_t = nullptr)
|
||||
: value(static_cast<s32>(value))
|
||||
{
|
||||
}
|
||||
@@ -948,7 +947,14 @@ struct error_code
|
||||
// Error constructor
|
||||
template<typename ET, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value)))
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), nullptr, 0))
|
||||
{
|
||||
}
|
||||
|
||||
// Error constructor (2 args)
|
||||
template<typename ET, typename T2, typename = std::enable_if_t<is_error<ET>::value>>
|
||||
error_code(const ET& value, const T2& value2)
|
||||
: value(error_report(fmt::get_type_info<fmt_unveil_t<ET>>(), fmt_unveil<ET>::get(value), fmt::get_type_info<fmt_unveil_t<T2>>(), fmt_unveil<T2>::get(value2)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</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 14 2015 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 15 2017 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 14 2015 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 15 2017 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 14 2015 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 15 2017 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 14 2015 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 15 2017 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 14 2015 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 15 2017 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 14 2015 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 15 2017 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>
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</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 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeReBuildCommandLine>cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
<NMakeCleanCommandLine>cmake -G "Visual Studio 15 2017 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 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
cmake -G "Visual Studio 14 2015 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_CONFIGURATION_TYPES="Debug;Release" ../glslang
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Debug /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
+10
-7
@@ -1,6 +1,6 @@
|
||||
version: '0.0.2-{build}'
|
||||
version: '0.0.3-{build}'
|
||||
|
||||
os: Visual Studio 2015
|
||||
os: Visual Studio 2017
|
||||
platform: x64
|
||||
clone_folder: C:\rpcs3
|
||||
clone_depth: 3
|
||||
@@ -15,8 +15,11 @@ before_build:
|
||||
- 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
|
||||
- if %configuration%==Release (cmake -G "Visual Studio 14 Win64" -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
else (7z x llvmlibs.7z -aos -oC:\rpcs3 > null && cmake -G "Visual Studio 14 Win64" -DLLVM_DIR=C:/rpcs3/llvm_build/lib/cmake/llvm -DZLIB_ROOT=C:/rpcs3/zlib/ -DVULKAN_PREBUILT=ON)
|
||||
- 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_script:
|
||||
- cmake --build . --config Release -- /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
||||
@@ -25,14 +28,14 @@ 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.8\msvc2015_64
|
||||
- set QTDIR=C:\Qt\5.9.1\msvc2017_64
|
||||
- set OPENALDIR=C:\rpcs3\3rdparty\OpenAL
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\14.0\Bin;%QTDIR%;%PATH%
|
||||
- set PATH=C:\Program Files (x86)\MSBuild\15.0\Bin;%QTDIR%;%PATH%
|
||||
- set COMMIT_SHA=%APPVEYOR_REPO_COMMIT:~0,8%
|
||||
|
||||
artifacts:
|
||||
- path: bin
|
||||
name: 'rpcs3-v0.0.2-$(Date)-$(COMMIT_SHA)_win64'
|
||||
name: 'rpcs3-v0.0.3-$(Date)-$(COMMIT_SHA)_win64'
|
||||
type: zip
|
||||
|
||||
cache:
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Kuroi (Dark) Theme for RPCS3
|
||||
by Ani @ https://github.com/AniLeo
|
||||
r1 (2017.08.15)
|
||||
*/
|
||||
|
||||
/*
|
||||
Color Scheme
|
||||
(Darker to Lighter)
|
||||
|
||||
Black
|
||||
> 292929
|
||||
> 323232
|
||||
> 333333
|
||||
> 3d3d3d
|
||||
> 404040
|
||||
> 444444
|
||||
|
||||
Light Grey
|
||||
> 828790
|
||||
> bdc3c7
|
||||
> ecf0f1
|
||||
|
||||
> b1b1b1
|
||||
> 7f8c8d
|
||||
|
||||
Green
|
||||
> 2ecc71
|
||||
|
||||
Red
|
||||
> e74c3c
|
||||
*/
|
||||
|
||||
/* Every widget */
|
||||
QWidget {
|
||||
background-color: #323232;
|
||||
color: #bdc3c7;
|
||||
alternate-background-color: #3d3d3d;
|
||||
}
|
||||
|
||||
/* Mouse tooltips */
|
||||
QToolTip {
|
||||
border: 1px solid #323232;
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Table headers */
|
||||
QHeaderView::section {
|
||||
background-color: #323232;
|
||||
color: #ecf0f1;
|
||||
padding-left: 4px;
|
||||
border: 1px solid #323232;
|
||||
}
|
||||
|
||||
/* Settings Dialog: Tabs */
|
||||
QTabBar::tab {
|
||||
color: #ecf0f1;
|
||||
border: 1px solid #444;
|
||||
border-bottom-style: none;
|
||||
background-color: #333333;
|
||||
padding-left: 16px;
|
||||
padding-right: 16px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
QTabBar::tab:last {
|
||||
margin-right: 0px;
|
||||
}
|
||||
QTabBar::tab:!selected {
|
||||
color: #b1b1b1;
|
||||
border-bottom-style: solid;
|
||||
margin-top: 3px;
|
||||
background-color: #292929;
|
||||
}
|
||||
QTabBar::tab:hover {
|
||||
background-color: #333333;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
QCheckBox::indicator {
|
||||
border-radius: 2px;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
QCheckBox::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QCheckBox::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QCheckBox::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Radio Buttons */
|
||||
QRadioButton::indicator {
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ecf0f1;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: 1px;
|
||||
}
|
||||
QRadioButton::indicator:checked {
|
||||
background-color: #2ecc71; /* Green */
|
||||
}
|
||||
QRadioButton::indicator:unchecked {
|
||||
background-color: #e74c3c; /* Red */
|
||||
}
|
||||
QRadioButton::indicator::disabled {
|
||||
background-color: #7f8c8d; /* Gray */
|
||||
}
|
||||
|
||||
/* Combo Boxes */
|
||||
QComboBox {
|
||||
background-color: #404040;
|
||||
color: #fff;
|
||||
border: 1px solid #1e1e1e;
|
||||
border-radius: 3px;
|
||||
padding-bottom: 2px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
QComboBox::disabled {
|
||||
background-color: #828790;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Group Boxes (Settings Dialog) */
|
||||
QGroupBox {
|
||||
margin-top: 17px;
|
||||
font-size: 13px;
|
||||
border: 1px solid #bdc3c7;
|
||||
border-radius: 4px;
|
||||
}
|
||||
QGroupBox::title {
|
||||
subcontrol-origin: margin;
|
||||
subcontrol-position: top center;
|
||||
padding: 5px 10px 5px 10px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
QPushButton {
|
||||
background-color: #404040;
|
||||
}
|
||||
QPushButton::disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Log and Debugger borders */
|
||||
QTextEdit {
|
||||
border: 1px solid #828790;
|
||||
}
|
||||
|
||||
/* For dock buttons to be visible */
|
||||
QDockWidget::close-button, QDockWidget::float-button {
|
||||
background-color: #bdc3c7;
|
||||
border: 1px solid #000;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Disable ugly borders */
|
||||
QTabWidget::pane {
|
||||
border: 0px solid #828790;
|
||||
}
|
||||
|
||||
/* Top menu bar */
|
||||
QMenuBar::item:selected {
|
||||
background: #444444;
|
||||
}
|
||||
QMenu::item {
|
||||
padding-left: 20px;
|
||||
padding-right: 15px;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
QMenu::item:selected {
|
||||
background: #444444;
|
||||
border: 1px solid #bdc3c7;
|
||||
}
|
||||
QMenu::item:disabled {
|
||||
background-color: #444444;
|
||||
color: #828790;
|
||||
}
|
||||
|
||||
/* Libraries list */
|
||||
QListWidget::item:selected {
|
||||
background-color: #3d3d3d;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
QListWidget::item:hover {
|
||||
background-color: #4c4b4b;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Pad Settings: Controller Image */
|
||||
QLabel#l_controller {
|
||||
color: #bdc3c7;
|
||||
}
|
||||
|
||||
/* Game Grid Font */
|
||||
QLabel#gamegrid_font {
|
||||
font-weight: 600;
|
||||
font-size: 8pt;
|
||||
font-family: Lucida Grande;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Slider on toolbar */
|
||||
QWidget#sizeSliderContainer {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Debug UI Settings buttons */
|
||||
QLabel#color_button {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Seachbar on main toolbar */
|
||||
QLineEdit#mw_searchbar {
|
||||
margin-left:14px;
|
||||
color: #ecf0f1;
|
||||
}
|
||||
|
||||
/* Uniform colors in Toolbar */
|
||||
QToolButton {
|
||||
background: transparent;
|
||||
color: transparent;
|
||||
}
|
||||
QToolButton::disabled {
|
||||
background-color: #828790;
|
||||
}
|
||||
QToolButton::hover {
|
||||
background-color: #444444;
|
||||
}
|
||||
|
||||
/* Set Theme UI colors */
|
||||
QLabel#gamelist_icon_background_color {
|
||||
background-color: #323232;
|
||||
}
|
||||
QLabel#gamelist_toolbar_icon_color {
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
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 +0,0 @@
|
||||
make_fself compiled.elf EBOOT.BIN
|
||||
Binary file not shown.
+1
-1
Submodule llvm updated: 4423e35117...a3b2103ffc
@@ -18,12 +18,12 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Makefile</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -39,30 +39,30 @@
|
||||
<NMakePreprocessorDefinitions>
|
||||
</NMakePreprocessorDefinitions>
|
||||
<NMakeBuildCommandLine>
|
||||
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
|
||||
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
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Debug /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
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
|
||||
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
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Debug /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
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
|
||||
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
|
||||
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 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
|
||||
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
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:build /p:Configuration=Release /m
|
||||
</NMakeBuildCommandLine>
|
||||
<NMakeReBuildCommandLine>
|
||||
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
|
||||
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
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:rebuild /p:Configuration=Release /m
|
||||
</NMakeReBuildCommandLine>
|
||||
<NMakeCleanCommandLine>
|
||||
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
|
||||
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
|
||||
msbuild.exe ALL_BUILD.vcxproj /t:clean /p:Configuration=Release /m
|
||||
</NMakeCleanCommandLine>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// http://stackoverflow.com/a/34032216/78204
|
||||
|
||||
function Controller() {
|
||||
installer.autoRejectMessageBoxes();
|
||||
installer.setMessageBoxAutomaticAnswer("OverwriteTargetDirectory", QMessageBox.Yes);
|
||||
installer.installationFinished.connect(function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
})
|
||||
}
|
||||
|
||||
Controller.prototype.WelcomePageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.CredentialsPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.IntroductionPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.TargetDirectoryPageCallback = function()
|
||||
{
|
||||
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt");
|
||||
//gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("InstallerDirPath") + "/Qt");
|
||||
//gui.currentPageWidget().TargetDirectoryLineEdit.setText("/scratch/Qt");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
var widget = gui.currentPageWidget();
|
||||
|
||||
widget.deselectAll();
|
||||
widget.selectComponent("qt.591.gcc_64");
|
||||
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.LicenseAgreementPageCallback = function() {
|
||||
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.StartMenuDirectoryPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ReadyForInstallationPageCallback = function()
|
||||
{
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.FinishedPageCallback = function() {
|
||||
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
|
||||
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
|
||||
checkBoxForm.launchQtCreatorCheckBox.checked = false;
|
||||
}
|
||||
gui.clickButton(buttons.FinishButton);
|
||||
}
|
||||
@@ -20,14 +20,14 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</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 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26430.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "asmjit", "asmjitsrc\asmjit.vcxproj", "{AC40FF01-426E-4838-A317-66354CEFAE88}"
|
||||
EndProject
|
||||
|
||||
+70
-24
@@ -3,9 +3,10 @@ cmake_minimum_required(VERSION 3.0.2)
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake_modules")
|
||||
set(RES_FILES "")
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
# Qt section
|
||||
find_package(Qt5 5.7 COMPONENTS Widgets)
|
||||
find_package(Qt5 5.9 COMPONENTS Widgets)
|
||||
if (WIN32)
|
||||
find_package(Qt5WinExtras REQUIRED)
|
||||
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras)
|
||||
@@ -17,8 +18,8 @@ endif()
|
||||
|
||||
# Let's make sure we have Qt before we continue
|
||||
if (NOT Qt5Widgets_FOUND)
|
||||
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 (Qt5Widgets_VERSION VERSION_LESS 5.9.0)
|
||||
message("Minimum supported Qt5 version is 5.9! 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.
|
||||
@@ -37,7 +38,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.8\\msvc2017_64\\)")
|
||||
message(FATAL_ERROR "Make sure the QTDIR env variable has been set properly. (for example C:\\Qt\\5.9\\msvc2017_64\\)")
|
||||
elseif("${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
message(FATAL_ERROR "Make sure to install your distro's qt5 package!")
|
||||
else()
|
||||
@@ -84,10 +85,12 @@ else()
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
if($ENV{CI})
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O1") # fix for travis gcc OoM crash. Might be fixed with the move to containers.
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
|
||||
# This hides our LLVM from mesa's LLVM, otherwise we get some unresolvable conflicts.
|
||||
if(NOT APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--exclude-libs,ALL")
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
set(CMAKE_RC_COMPILER_INIT windres)
|
||||
enable_language(RC)
|
||||
@@ -97,11 +100,29 @@ if(NOT MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--allow-multiple-definition")
|
||||
endif()
|
||||
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3)
|
||||
add_compile_options(-msse -msse2 -mcx16 -mssse3 -mrtm)
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
# This fixes 'some' of the st11range issues. See issue #2516
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
|
||||
if(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-image_base,0x10000 -Wl,-pagezero_size,0x10000")
|
||||
else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -image-base=0x10000")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Some distros have the compilers set to use PIE by default, but RPCS3 doesn't work with PIE, so we need to disable it.
|
||||
if(APPLE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-no_pie")
|
||||
else()
|
||||
CHECK_C_COMPILER_FLAG("-no-pie" HAS_NO_PIE)
|
||||
CHECK_C_COMPILER_FLAG("-nopie" HAS_NOPIE)
|
||||
|
||||
if(HAS_NO_PIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -no-pie")
|
||||
elseif(HAS_NOPIE)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nopie")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(GLEW REQUIRED)
|
||||
@@ -115,7 +136,7 @@ endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
#on some Linux distros shm_unlink and similar functions are in librt only
|
||||
set(ADDITIONAL_LIBS "rt" "X11" "asound")
|
||||
set(ADDITIONAL_LIBS "rt" "X11")
|
||||
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
|
||||
@@ -146,6 +167,37 @@ elseif(WIN32)
|
||||
set(PLATFORM_ARCH "Windows/x86_64")
|
||||
else()
|
||||
set(PLATFORM_ARCH "linux/x86_64")
|
||||
option(USE_ALSA "ALSA audio backend" ON)
|
||||
option(USE_PULSE "PulseAudio audio backend" ON)
|
||||
option(USE_LIBEVDEV "libevdev-based joystick support" ON)
|
||||
endif()
|
||||
|
||||
if(USE_ALSA)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(ALSA alsa)
|
||||
if(ALSA_FOUND)
|
||||
add_definitions(-DHAVE_ALSA)
|
||||
include_directories(SYSTEM ${ALSA_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${ALSA_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(USE_PULSE)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PULSE libpulse-simple)
|
||||
if(PULSE_FOUND)
|
||||
add_definitions(-DHAVE_PULSE)
|
||||
include_directories(SYSTEM ${PULSE_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${PULSE_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
if(USE_LIBEVDEV)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBEVDEV libevdev)
|
||||
if(LIBEVDEV_FOUND)
|
||||
add_definitions(-DHAVE_LIBEVDEV)
|
||||
include_directories(SYSTEM ${LIBEVDEV_INCLUDE_DIRS})
|
||||
list(APPEND ADDITIONAL_LIBS ${LIBEVDEV_LDFLAGS})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Select the version of libpng to use, default is builtin
|
||||
@@ -202,16 +254,10 @@ if(NOT LLVM_FOUND)
|
||||
else()
|
||||
add_definitions(${LLVM_DEFINITIONS})
|
||||
add_definitions(-DLLVM_AVAILABLE)
|
||||
|
||||
#Use static linking for windows binary but always dynamic on *nix
|
||||
if (WIN32)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
|
||||
else()
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
endif()
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler)
|
||||
else()
|
||||
set(LLVM_LIBS LLVM)
|
||||
llvm_map_components_to_libnames(LLVM_LIBS mcjit vectorize ipo x86codegen x86disassembler mcdisassembler)
|
||||
endif()
|
||||
|
||||
if (NOT MSVC)
|
||||
@@ -268,12 +314,10 @@ if(NOT WIN32 AND NOT "${CMAKE_SYSTEM}" MATCHES "Linux")
|
||||
set (EXCLUDE_FILES "/RSX/VK/")
|
||||
endif()
|
||||
|
||||
# The Gui folder contains wxWidgets stuff, which we no longer want.
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "/Gui/")
|
||||
|
||||
# Ignore autogenerated moc_* files if present
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "moc_")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "rpcs3_automoc")
|
||||
set (EXCLUDE_FILES ${EXCLUDE_FILES} "qrc_resources.cpp")
|
||||
|
||||
foreach (TMP_PATH ${RPCS3_SRC})
|
||||
foreach (EXCLUDE_PATH ${EXCLUDE_FILES})
|
||||
@@ -285,7 +329,7 @@ foreach (TMP_PATH ${RPCS3_SRC})
|
||||
endforeach(TMP_PATH)
|
||||
|
||||
# Remove the Qt moc files as part of clean, they are compiled when generating automoc
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp")
|
||||
file(GLOB_RECURSE TMP_MOC "${RPCS3_SRC_DIR}/moc_*.cpp" "${RPCS3_SRC_DIR}/rpcs3_automoc.cpp" "${RPCS3_SRC_DIR}/qrc_resources.cpp")
|
||||
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${TMP_MOC}")
|
||||
|
||||
if (WIN32)
|
||||
@@ -306,7 +350,9 @@ if(WIN32)
|
||||
target_link_libraries(rpcs3 avformat.lib avcodec.lib avutil.lib swresample.lib swscale.lib png16_static ${OPENAL_LIBRARY} ${ADDITIONAL_LIBS})
|
||||
else()
|
||||
target_link_libraries(rpcs3 ${OPENAL_LIBRARY} ${GLEW_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
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)
|
||||
else()
|
||||
target_link_libraries(rpcs3 hidapi-libusb usb)
|
||||
|
||||
@@ -150,8 +150,8 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np
|
||||
const int metadata_section_size = ((edat->flags & EDAT_COMPRESSED_FLAG) != 0 || (edat->flags & EDAT_FLAG_0x20) != 0) ? 0x20 : 0x10;
|
||||
const int metadata_offset = 0x100;
|
||||
|
||||
std::unique_ptr<u8> enc_data;
|
||||
std::unique_ptr<u8> dec_data;
|
||||
std::unique_ptr<u8[]> enc_data;
|
||||
std::unique_ptr<u8[]> dec_data;
|
||||
u8 hash[0x10] = { 0 };
|
||||
u8 key_result[0x10] = { 0 };
|
||||
u8 hash_result[0x14] = { 0 };
|
||||
@@ -315,7 +315,7 @@ int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD
|
||||
{
|
||||
const int total_blocks = (int)((edat->file_size + edat->block_size - 1) / edat->block_size);
|
||||
u64 size_left = (int)edat->file_size;
|
||||
std::unique_ptr<u8> data(new u8[edat->block_size]);
|
||||
std::unique_ptr<u8[]> data(new u8[edat->block_size]);
|
||||
|
||||
for (int i = 0; i < total_blocks; i++)
|
||||
{
|
||||
@@ -427,8 +427,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
|
||||
long bytes_read = 0;
|
||||
long bytes_to_read = metadata_size;
|
||||
std::unique_ptr<u8> metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8> empty_metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8[]> metadata(new u8[metadata_size]);
|
||||
std::unique_ptr<u8[]> empty_metadata(new u8[metadata_size]);
|
||||
|
||||
while (bytes_to_read > 0)
|
||||
{
|
||||
@@ -487,7 +487,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
if ((edat->flags & EDAT_FLAG_0x20) != 0) //Sony failed again, they used buffer from 0x100 with half size of real metadata.
|
||||
{
|
||||
int metadata_buf_size = block_num * 0x10;
|
||||
std::unique_ptr<u8> metadata_buf(new u8[metadata_buf_size]);
|
||||
std::unique_ptr<u8[]> metadata_buf(new u8[metadata_buf_size]);
|
||||
f->seek(file_offset + metadata_offset);
|
||||
f->read(metadata_buf.get(), metadata_buf_size);
|
||||
sha1(metadata_buf.get(), metadata_buf_size, signature_hash);
|
||||
@@ -516,7 +516,7 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs:
|
||||
{
|
||||
// Setup header signature hash.
|
||||
memset(signature_hash, 0, 20);
|
||||
std::unique_ptr<u8> header_buf(new u8[0xD8]);
|
||||
std::unique_ptr<u8[]> header_buf(new u8[0xD8]);
|
||||
f->seek(file_offset);
|
||||
f->read(header_buf.get(), 0xD8);
|
||||
sha1(header_buf.get(), 0xD8, signature_hash );
|
||||
@@ -577,7 +577,7 @@ int validate_npd_hashes(const char* file_name, const u8* klicensee, NPD_HEADER *
|
||||
int dev_hash_result = 0;
|
||||
|
||||
const int file_name_length = (int) strlen(file_name);
|
||||
std::unique_ptr<u8> buf(new u8[0x30 + file_name_length]);
|
||||
std::unique_ptr<u8[]> buf(new u8[0x30 + file_name_length]);
|
||||
|
||||
// Build the title buffer (content_id + file_name).
|
||||
memcpy(buf.get(), npd->content_id, 0x30);
|
||||
|
||||
+90
-11
@@ -3,19 +3,77 @@
|
||||
#include "aes.h"
|
||||
#include "sha1.h"
|
||||
#include "key_vault.h"
|
||||
#include "Utilities/StrFmt.h"
|
||||
#include "unpkg.h"
|
||||
|
||||
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync)
|
||||
bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>& sync, const std::string& pkg_filepath)
|
||||
{
|
||||
const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB
|
||||
std::vector<fs::file> filelist;
|
||||
u32 cur_file=0;
|
||||
|
||||
fs::file original_file(pkg_filepath);
|
||||
original_file.seek(pkg_f.pos());
|
||||
|
||||
filelist.push_back(std::move(original_file));
|
||||
|
||||
// Save current file offset (probably zero)
|
||||
const u64 start_offset = pkg_f.pos();
|
||||
u64 cur_offset = start_offset;
|
||||
u64 cur_file_offset = start_offset;
|
||||
|
||||
// Get basic PKG information
|
||||
PKGHeader header;
|
||||
|
||||
if (!pkg_f.read(header))
|
||||
auto archive_seek = [&](const s64 new_offset, const fs::seek_mode damode = fs::seek_set)
|
||||
{
|
||||
if(damode == fs::seek_set) cur_offset = new_offset;
|
||||
else if (damode == fs::seek_cur) cur_offset += new_offset;
|
||||
|
||||
u64 _offset = 0;
|
||||
for (u32 i = 0; i < filelist.size(); i++)
|
||||
{
|
||||
if (cur_offset < (_offset + filelist[i].size()))
|
||||
{
|
||||
cur_file = i;
|
||||
cur_file_offset = cur_offset - _offset;
|
||||
filelist[i].seek(cur_file_offset);
|
||||
break;
|
||||
}
|
||||
_offset += filelist[i].size();
|
||||
}
|
||||
};
|
||||
|
||||
auto archive_read = [&](const void *data_ptr, const u64 num_bytes)
|
||||
{
|
||||
u64 num_bytes_left = filelist[cur_file].size() - cur_file_offset;
|
||||
//check if it continues in another file
|
||||
if (num_bytes > num_bytes_left)
|
||||
{
|
||||
filelist[cur_file].read((u8 *)data_ptr, num_bytes_left);
|
||||
if ((cur_file + 1) < filelist.size()) cur_file++;
|
||||
else
|
||||
{
|
||||
cur_offset += num_bytes_left;
|
||||
cur_file_offset = filelist[cur_file].size();
|
||||
return num_bytes_left;
|
||||
}
|
||||
u64 num_read = filelist[cur_file].read((u8 *)data_ptr + num_bytes_left, num_bytes - num_bytes_left);
|
||||
cur_offset += (num_read + num_bytes_left);
|
||||
cur_file_offset = num_read;
|
||||
return (num_read+num_bytes_left);
|
||||
}
|
||||
|
||||
u64 num_read = filelist[cur_file].read((u8 *)data_ptr, num_bytes);
|
||||
|
||||
cur_offset += num_read;
|
||||
cur_file_offset += num_read;
|
||||
|
||||
return num_read;
|
||||
};
|
||||
|
||||
|
||||
if (archive_read(&header, sizeof(header)) != sizeof(header))
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file is too short!");
|
||||
return false;
|
||||
@@ -51,8 +109,29 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
|
||||
if (header.pkg_size > pkg_f.size())
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
|
||||
return false;
|
||||
//Check if multi-files pkg
|
||||
if (pkg_filepath.length() < 7 || pkg_filepath.substr(pkg_filepath.length() - 7).compare("_00.pkg") != 0)
|
||||
{
|
||||
LOG_ERROR(LOADER, "PKG file size mismatch (pkg_size=0x%llx)", header.pkg_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name_wo_number = pkg_filepath.substr(0, pkg_filepath.length() - 7);
|
||||
u64 cursize = pkg_f.size();
|
||||
while (cursize != header.pkg_size)
|
||||
{
|
||||
std::string archive_filename = fmt::format("%s_%2d.pkg", name_wo_number, filelist.size());
|
||||
|
||||
fs::file archive_file(archive_filename);
|
||||
if (!archive_file)
|
||||
{
|
||||
LOG_ERROR(LOADER, "Missing part of the multi-files pkg: %s", archive_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
cursize += archive_file.size();
|
||||
filelist.push_back(std::move(archive_file));
|
||||
}
|
||||
}
|
||||
|
||||
if (header.data_size + header.data_offset > header.pkg_size)
|
||||
@@ -64,7 +143,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
be_t<u32> drm_type{0};
|
||||
be_t<u32> content_type{0};
|
||||
|
||||
pkg_f.seek(header.pkg_info_off);
|
||||
archive_seek(header.pkg_info_off);
|
||||
|
||||
for (u32 i = 0; i < header.pkg_info_num; i++)
|
||||
{
|
||||
@@ -74,7 +153,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
be_t<u32> size;
|
||||
} packet;
|
||||
|
||||
pkg_f.read(packet);
|
||||
archive_read(&packet, sizeof(packet));
|
||||
|
||||
// TODO
|
||||
switch (+packet.id)
|
||||
@@ -83,7 +162,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
{
|
||||
if (packet.size == sizeof(drm_type))
|
||||
{
|
||||
pkg_f.read(drm_type);
|
||||
archive_read(&drm_type, sizeof(drm_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -93,7 +172,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
{
|
||||
if (packet.size == sizeof(content_type))
|
||||
{
|
||||
pkg_f.read(content_type);
|
||||
archive_read(&content_type, sizeof(content_type));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -101,7 +180,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
}
|
||||
}
|
||||
|
||||
pkg_f.seek(packet.size, fs::seek_cur);
|
||||
archive_seek(packet.size, fs::seek_cur);
|
||||
}
|
||||
|
||||
// Allocate buffer with BUF_SIZE size or more if required
|
||||
@@ -110,10 +189,10 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, atomic_t<double>
|
||||
// Define decryption subfunction (`psp` arg selects the key for specific block)
|
||||
auto decrypt = [&](u64 offset, u64 size, const uchar* key) -> u64
|
||||
{
|
||||
pkg_f.seek(start_offset + header.data_offset + offset);
|
||||
archive_seek(start_offset + header.data_offset + offset);
|
||||
|
||||
// Read the data and set available size
|
||||
const u64 read = pkg_f.read(buf.get(), size);
|
||||
const u64 read = archive_read(buf.get(), size);
|
||||
|
||||
// Get block count
|
||||
const u64 blocks = (read + 15) / 16;
|
||||
|
||||
@@ -57,4 +57,4 @@ struct PKGEntry
|
||||
be_t<u32> pad; // Padding (zeros)
|
||||
};
|
||||
|
||||
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, atomic_t<double>&);
|
||||
bool pkg_install(const class fs::file& pkg_f, const std::string& dir, atomic_t<double>&, const std::string& pkg_filepath);
|
||||
|
||||
@@ -118,7 +118,7 @@ void aesecb128_encrypt(unsigned char *key, unsigned char *in, unsigned char *out
|
||||
|
||||
bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
|
||||
{
|
||||
std::unique_ptr<u8> out(new u8[key_len]);
|
||||
std::unique_ptr<u8[]> out(new u8[key_len]);
|
||||
|
||||
sha1_hmac(key, key_len, in, in_len, out.get());
|
||||
|
||||
@@ -132,7 +132,7 @@ void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_
|
||||
|
||||
bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
|
||||
{
|
||||
std::unique_ptr<u8> out(new u8[key_len]);
|
||||
std::unique_ptr<u8[]> out(new u8[key_len]);
|
||||
|
||||
aes_context ctx;
|
||||
aes_setkey_enc(&ctx, key, 128);
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "ALSAThread.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
#ifdef HAVE_ALSA
|
||||
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#include "Emu/System.h"
|
||||
#include "PulseThread.h"
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
|
||||
#include <pulse/simple.h>
|
||||
#include <pulse/error.h>
|
||||
|
||||
PulseThread::PulseThread()
|
||||
{
|
||||
}
|
||||
|
||||
PulseThread::~PulseThread()
|
||||
{
|
||||
this->Close();
|
||||
}
|
||||
|
||||
void PulseThread::Play()
|
||||
{
|
||||
}
|
||||
|
||||
void PulseThread::Close()
|
||||
{
|
||||
if(this->connection) {
|
||||
pa_simple_free(this->connection);
|
||||
this->connection = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void PulseThread::Stop()
|
||||
{
|
||||
}
|
||||
|
||||
void PulseThread::Open(const void* src, int size)
|
||||
{
|
||||
pa_sample_spec ss;
|
||||
ss.format = g_cfg.audio.convert_to_u16 ? PA_SAMPLE_S16LE : PA_SAMPLE_FLOAT32LE;
|
||||
ss.channels = g_cfg.audio.downmix_to_2ch ? 2 : 8;
|
||||
ss.rate = 48000;
|
||||
|
||||
int err;
|
||||
this->connection = pa_simple_new(NULL, "RPCS3", PA_STREAM_PLAYBACK, NULL, "Game", &ss, NULL, NULL, &err);
|
||||
if(!this->connection) {
|
||||
fprintf(stderr, "PulseAudio: Failed to initialize audio: %s\n", pa_strerror(err));
|
||||
}
|
||||
|
||||
this->AddData(src, size);
|
||||
}
|
||||
|
||||
void PulseThread::AddData(const void* src, int size)
|
||||
{
|
||||
if(this->connection) {
|
||||
int err;
|
||||
if(pa_simple_write(this->connection, src, size, &err) < 0) {
|
||||
fprintf(stderr, "PulseAudio: Failed to write audio stream: %s\n", pa_strerror(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef HAVE_PULSE
|
||||
#include <pulse/simple.h>
|
||||
#include "Emu/Audio/AudioThread.h"
|
||||
|
||||
class PulseThread : public AudioThread
|
||||
{
|
||||
public:
|
||||
PulseThread();
|
||||
virtual ~PulseThread() override;
|
||||
|
||||
virtual void Play() override;
|
||||
virtual void Open(const void* src, int size) override;
|
||||
virtual void Close() override;
|
||||
virtual void Stop() override;
|
||||
virtual void AddData(const void* src, int size) override;
|
||||
|
||||
private:
|
||||
pa_simple *connection = nullptr;
|
||||
};
|
||||
|
||||
#endif
|
||||
+22
-4
@@ -1,9 +1,12 @@
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
#include "Emu/Cell/SPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_sync.h"
|
||||
#include "MFC.h"
|
||||
|
||||
const bool s_use_rtm = utils::has_rtm();
|
||||
|
||||
template <>
|
||||
void fmt_class_string<MFC>::format(std::string& out, u64 arg)
|
||||
{
|
||||
@@ -145,10 +148,25 @@ void mfc_thread::cpu_task()
|
||||
vm::reservation_acquire(cmd.eal, 128);
|
||||
|
||||
// Store unconditionally
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
if (s_use_rtm && utils::transaction_enter())
|
||||
{
|
||||
if (!vm::reader_lock{vm::try_to_lock})
|
||||
{
|
||||
_xabort(0);
|
||||
}
|
||||
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
_xend();
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
data = to_write;
|
||||
vm::reservation_update(cmd.eal, 128);
|
||||
vm::notify(cmd.eal, 128);
|
||||
}
|
||||
}
|
||||
else if (cmd.cmd & MFC_LIST_MASK)
|
||||
{
|
||||
|
||||
@@ -195,6 +195,12 @@ s32 cellAtracGetInternalErrorInfo(vm::ptr<CellAtracHandle> pHandle, vm::ptr<s32>
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAtracGetSamplingRate()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAtrac);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellAtrac)("cellAtrac", []()
|
||||
{
|
||||
REG_FUNC(cellAtrac, cellAtracSetDataAndGetMemSize);
|
||||
@@ -227,4 +233,6 @@ DECLARE(ppu_module_manager::cellAtrac)("cellAtrac", []()
|
||||
REG_FUNC(cellAtrac, cellAtracResetPlayPosition);
|
||||
|
||||
REG_FUNC(cellAtrac, cellAtracGetInternalErrorInfo);
|
||||
|
||||
REG_FUNC(cellAtrac, cellAtracGetSamplingRate);
|
||||
});
|
||||
|
||||
@@ -203,6 +203,12 @@ s32 cellAtracMultiGetInternalErrorInfo(vm::ptr<CellAtracMultiHandle> pHandle, vm
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAtracMultiGetSamplingRate()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAtracMulti);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellAtracMulti)("cellAtracMulti", []()
|
||||
{
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiSetDataAndGetMemSize);
|
||||
@@ -236,4 +242,6 @@ DECLARE(ppu_module_manager::cellAtracMulti)("cellAtracMulti", []()
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiResetPlayPosition);
|
||||
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiGetInternalErrorInfo);
|
||||
|
||||
REG_FUNC(cellAtracMulti, cellAtracMultiGetSamplingRate);
|
||||
});
|
||||
|
||||
@@ -11,39 +11,39 @@ logs::channel cellAvconfExt("cellAvconfExt");
|
||||
|
||||
vm::gvar<f32> g_gamma; // TODO
|
||||
|
||||
s32 cellAudioOutUnregisterDevice()
|
||||
s32 cellAudioOutUnregisterDevice(u32 deviceNumber)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutUnregisterDevice(deviceNumber=0x%x)", deviceNumber);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutGetDeviceInfo2()
|
||||
s32 cellAudioOutGetDeviceInfo2(u32 deviceNumber, u32 deviceIndex, vm::ptr<CellAudioOutDeviceInfo2> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutGetDeviceInfo2(deviceNumber=0x%x, deviceIndex=0x%x, info=*0x%x)", deviceNumber, deviceIndex, info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetXVColor()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetupDisplay()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInGetDeviceInfo()
|
||||
s32 cellAudioInGetDeviceInfo(u32 deviceNumber, u32 deviceIndex, vm::ptr<CellAudioInDeviceInfo> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInGetDeviceInfo(deviceNumber=0x%x, deviceIndex=0x%x, info=*0x%x)", deviceNumber, deviceIndex, info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutConvertCursorColor()
|
||||
s32 cellVideoOutConvertCursorColor(u32 videoOut, s32 displaybuffer_format, f32 gamma, s32 source_buffer_format, vm::ptr<void> src_addr, vm::ptr<u32> dest_addr, s32 num)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellVideoOutConvertCursorColor(videoOut=%d, displaybuffer_format=0x%x, gamma=0x%x, source_buffer_format=0x%x, src_addr=*0x%x, dest_addr=*0x%x, num=0x%x)", videoOut, displaybuffer_format, gamma, source_buffer_format, src_addr, dest_addr, num);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -61,16 +61,16 @@ s32 cellVideoOutGetGamma(u32 videoOut, vm::ptr<f32> gamma)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInGetAvailableDeviceInfo()
|
||||
s32 cellAudioInGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioInDeviceInfo> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
cellAvconfExt.todo("cellAudioInGetAvailableDeviceInfo(count=0x%x, info=*0x%x)", count, info);
|
||||
return 0; // number of available devices
|
||||
}
|
||||
|
||||
s32 cellAudioOutGetAvailableDeviceInfo()
|
||||
s32 cellAudioOutGetAvailableDeviceInfo(u32 count, vm::ptr<CellAudioOutDeviceInfo2> info)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
cellAvconfExt.todo("cellAudioOutGetAvailableDeviceInfo(count=0x%x, info=*0x%x)", count, info);
|
||||
return 0; // number of available devices
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetGamma(u32 videoOut, f32 gamma)
|
||||
@@ -92,37 +92,37 @@ s32 cellVideoOutSetGamma(u32 videoOut, f32 gamma)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutRegisterDevice()
|
||||
s32 cellAudioOutRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::ptr<CellAudioOutRegistrationOption> option, vm::ptr<CellAudioOutDeviceConfiguration> config)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioOutRegisterDevice(deviceType=0x%llx, name=%s, option=*0x%x, config=*0x%x)", deviceType, name, option, config);
|
||||
return 0; // device number
|
||||
}
|
||||
|
||||
s32 cellAudioOutSetDeviceMode(u32 deviceMode)
|
||||
{
|
||||
cellAvconfExt.todo("cellAudioOutSetDeviceMode(deviceMode=0x%x)", deviceMode);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioOutSetDeviceMode()
|
||||
s32 cellAudioInSetDeviceMode(u32 deviceMode)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInSetDeviceMode(deviceMode=0x%x)", deviceMode);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInSetDeviceMode()
|
||||
s32 cellAudioInRegisterDevice(u64 deviceType, vm::cptr<char> name, vm::ptr<CellAudioInRegistrationOption> option, vm::ptr<CellAudioInDeviceConfiguration> config)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
cellAvconfExt.todo("cellAudioInRegisterDevice(deviceType=0x%llx, name=%s, option=*0x%x, config=*0x%x)", deviceType, name, option, config);
|
||||
return 0; // device number
|
||||
}
|
||||
|
||||
s32 cellAudioInUnregisterDevice(u32 deviceNumber)
|
||||
{
|
||||
cellAvconfExt.todo("cellAudioInUnregisterDevice(deviceNumber=0x%x)", deviceNumber);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInRegisterDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellAudioInUnregisterDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> screenSize)
|
||||
s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<f32> screenSize)
|
||||
{
|
||||
cellAvconfExt.warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize=*0x%x)", videoOut, screenSize);
|
||||
|
||||
@@ -143,6 +143,12 @@ s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> screenSize)
|
||||
return CELL_VIDEO_OUT_ERROR_VALUE_IS_NOT_SET;
|
||||
}
|
||||
|
||||
s32 cellVideoOutSetCopyControl(u32 videoOut, u32 control)
|
||||
{
|
||||
cellAvconfExt.todo("cellVideoOutSetCopyControl(videoOut=%d, control=0x%x)", videoOut, control);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
|
||||
{
|
||||
@@ -168,4 +174,5 @@ DECLARE(ppu_module_manager::cellAvconfExt)("cellSysutilAvconfExt", []()
|
||||
REG_FUNC(cellSysutilAvconfExt, cellAudioInRegisterDevice);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellAudioInUnregisterDevice);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellVideoOutGetScreenSize);
|
||||
REG_FUNC(cellSysutilAvconfExt, cellVideoOutSetCopyControl);
|
||||
});
|
||||
|
||||
@@ -2,16 +2,35 @@
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel cellCrossController("cellCrossController");
|
||||
|
||||
s32 cellCrossController_37E1F502() // LittleBigPlanet 2 and 3
|
||||
struct CellCrossControllerParam
|
||||
{
|
||||
cellCrossController.todo("cellCrossController_37E1F502");
|
||||
vm::bcptr<char> pPackageFileName;
|
||||
vm::bcptr<char> pSignatureFileName;
|
||||
vm::bcptr<char> pIconFileName;
|
||||
vm::bptr<void> option;
|
||||
};
|
||||
|
||||
struct CellCrossControllerPackageInfo
|
||||
{
|
||||
vm::bcptr<char> pTitle;
|
||||
vm::bcptr<char> pTitleId;
|
||||
vm::bcptr<char> pAppVer;
|
||||
};
|
||||
|
||||
using CellCrossControllerCallback = void(s32 status, s32 errorCode, vm::ptr<void> option, vm::ptr<void> userdata);
|
||||
|
||||
s32 cellCrossControllerInitialize(vm::cptr<CellCrossControllerParam> pParam, vm::cptr<CellCrossControllerPackageInfo> pPkgInfo, vm::ptr<CellCrossControllerCallback> cb, vm::ptr<void> userdata) // LittleBigPlanet 2 and 3
|
||||
{
|
||||
cellCrossController.todo("cellCrossControllerInitialize(pParam=*0x%x, pPkgInfo=*0x%x, cb=*0x%x, userdata=*0x%x)", pParam, pPkgInfo, cb, userdata);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellCrossController)("cellCrossController", []()
|
||||
{
|
||||
REG_FNID(cellCrossController, 0x37E1F502, cellCrossController_37E1F502);
|
||||
REG_FUNC(cellCrossController, cellCrossControllerInitialize);
|
||||
});
|
||||
|
||||
@@ -554,7 +554,7 @@ s32 cellFontExtend(u32 a1, u32 a2, u32 a3)
|
||||
//Something happens
|
||||
}
|
||||
//Something happens?
|
||||
return CELL_OK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
s32 cellFontRenderCharGlyphImageVertical()
|
||||
|
||||
@@ -80,14 +80,13 @@ struct content_permission final
|
||||
// SFO file
|
||||
psf::registry sfo;
|
||||
|
||||
// True if temporary directory is created and must be moved or deleted
|
||||
bool is_temporary = false;
|
||||
// Temporary directory path
|
||||
std::string temp;
|
||||
|
||||
template <typename Dir, typename Sfo>
|
||||
content_permission(Dir&& dir, Sfo&& sfo, bool is_temp = false)
|
||||
content_permission(Dir&& dir, Sfo&& sfo)
|
||||
: dir(std::forward<Dir>(dir))
|
||||
, sfo(std::forward<Sfo>(sfo))
|
||||
, is_temporary(is_temp)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -95,9 +94,9 @@ struct content_permission final
|
||||
{
|
||||
try
|
||||
{
|
||||
if (is_temporary)
|
||||
if (!temp.empty())
|
||||
{
|
||||
fs::remove_all(vfs::get("/dev_hdd1/game/" + dir));
|
||||
fs::remove_all(temp);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
@@ -183,13 +182,14 @@ s32 cellHddGameGetSizeKB(vm::ptr<u32> size)
|
||||
{
|
||||
cellGame.warning("cellHddGameGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const std::string& local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
const std::string local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_HDDGAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -209,16 +209,16 @@ s32 cellGameDataGetSizeKB(vm::ptr<u32> size)
|
||||
{
|
||||
cellGame.warning("cellGameDataGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const std::string& local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
const std::string local_dir = vfs::get("/dev_hdd0/game/" + Emu.GetTitleID());
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_GAMEDATA_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
|
||||
}
|
||||
|
||||
s32 cellGameDataSetSystemVer()
|
||||
@@ -262,7 +262,7 @@ error_code cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr
|
||||
return CELL_GAME_ERROR_BUSY;
|
||||
}
|
||||
}
|
||||
else if (category == "AP" || category == "AV" || category == "HG")
|
||||
else if (category == "AP" || category == "AV" || category == "HG" || category == "AT" || category == "AM" || category == "SF")
|
||||
{
|
||||
*type = CELL_GAME_GAMETYPE_HDD;
|
||||
*attributes = 0; // TODO
|
||||
@@ -383,7 +383,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
|
||||
const std::string dir = prm->dir.empty() ? "/dev_bdvd/PS3_GAME"s : "/dev_hdd0/game/" + prm->dir;
|
||||
|
||||
if (prm->is_temporary)
|
||||
if (!prm->temp.empty())
|
||||
{
|
||||
// Make temporary directory persistent
|
||||
const auto vdir = vfs::get(dir);
|
||||
@@ -393,7 +393,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
fmt::throw_exception("cellGameContentPermit(): epic fail: directory '%s' already exists", dir);
|
||||
}
|
||||
|
||||
if (fs::rename(vfs::get("/dev_hdd1/game/" + prm->dir), vdir))
|
||||
if (fs::rename(prm->temp, vdir, false))
|
||||
{
|
||||
cellGame.success("cellGameContentPermit(): directory '%s' has been created", dir);
|
||||
}
|
||||
@@ -406,7 +406,7 @@ error_code cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPa
|
||||
psf::save_object(fs::file(vdir + "/PARAM.SFO", fs::rewrite), prm->sfo);
|
||||
|
||||
// Disable deletion
|
||||
prm->is_temporary = false;
|
||||
prm->temp.clear();
|
||||
}
|
||||
|
||||
strcpy_trunc(*contentInfoPath, dir);
|
||||
@@ -570,8 +570,8 @@ error_code cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<c
|
||||
strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo);
|
||||
strcpy_trunc(*tmp_usrdirPath, tmp_usrdir);
|
||||
|
||||
prm->temp = vfs::get(tmp_contentInfo);
|
||||
cellGame.success("cellGameCreateGameData(): temporary directory '%s' has been created", tmp_contentInfo);
|
||||
prm->is_temporary = true;
|
||||
|
||||
// Initial PARAM.SFO parameters (overwrite)
|
||||
prm->sfo =
|
||||
@@ -714,9 +714,10 @@ error_code cellGameSetParamString(s32 id, vm::cptr<char> buf)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
error_code cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
{
|
||||
cellGame.warning("cellGameGetSizeKB(size=*0x%x)", size);
|
||||
|
||||
const auto prm = fxm::get<content_permission>();
|
||||
|
||||
if (!prm)
|
||||
@@ -724,13 +725,14 @@ s32 cellGameGetSizeKB(vm::ptr<s32> size)
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const std::string& local_dir = prm->is_temporary? vfs::get("/dev_hdd1/game/"s + prm->dir) : vfs::get("/dev_hdd0/game/"s + prm->dir); //should we check the temporary folder?
|
||||
const std::string local_dir = !prm->temp.empty() ? prm->temp : vfs::get("/dev_hdd0/game/" + prm->dir);
|
||||
|
||||
if (!fs::is_dir(local_dir))
|
||||
{
|
||||
return CELL_GAME_ERROR_FAILURE;
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
*size = (u32)(fs::get_dir_size(local_dir)/1024);
|
||||
*size = ::narrow<u32>(fs::get_dir_size(local_dir) / 1024);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -5,14 +5,15 @@
|
||||
|
||||
logs::channel cellGameExec("cellGameExec");
|
||||
|
||||
s32 cellGameSetExitParam()
|
||||
s32 cellGameSetExitParam(u32 execdata)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellGameExec.todo("cellGameSetExitParam(execdata=0x%x)", execdata);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeDataExportPath(vm::ptr<char> exportPath)
|
||||
{
|
||||
cellGameExec.warning("cellGameGetHomeDataExportPath(exportPath=0x%x)", exportPath);
|
||||
cellGameExec.warning("cellGameGetHomeDataExportPath(exportPath=*0x%x)", exportPath);
|
||||
|
||||
// TODO: PlayStation home is defunct.
|
||||
|
||||
@@ -21,12 +22,17 @@ s32 cellGameGetHomeDataExportPath(vm::ptr<char> exportPath)
|
||||
|
||||
s32 cellGameGetHomePath()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
UNIMPLEMENTED_FUNC(cellGameExec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeDataImportPath()
|
||||
s32 cellGameGetHomeDataImportPath(vm::ptr<char> importPath)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellGameExec.warning("cellGameGetHomeDataImportPath(importPath=*0x%x)", importPath);
|
||||
|
||||
// TODO: PlayStation home is defunct.
|
||||
|
||||
return CELL_GAME_ERROR_NOAPP;
|
||||
}
|
||||
|
||||
s32 cellGameGetHomeLaunchOptionPath(vm::ptr<char> commonPath, vm::ptr<char> personalPath)
|
||||
@@ -37,9 +43,9 @@ s32 cellGameGetHomeLaunchOptionPath(vm::ptr<char> commonPath, vm::ptr<char> pers
|
||||
return CELL_GAME_ERROR_NOAPP;
|
||||
}
|
||||
|
||||
s32 cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm::ptr<u32> execData)
|
||||
s32 cellGameGetBootGameInfo(vm::ptr<u32> type, vm::ptr<char> dirName, vm::ptr<u32> execdata)
|
||||
{
|
||||
cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execData=*0x%x)", type, dirName, execData);
|
||||
cellGameExec.todo("cellGameGetBootGameInfo(type=*0x%x, dirName=%s, execdata=*0x%x)", type, dirName, execdata);
|
||||
|
||||
// TODO: Support more boot types
|
||||
*type = CELL_GAME_GAMETYPE_SYS;
|
||||
|
||||
@@ -26,16 +26,19 @@ const u32 tiled_pitches[] = {
|
||||
0x00010000
|
||||
};
|
||||
|
||||
struct CellGcmSysConfig {
|
||||
u32 zculls_addr;
|
||||
vm::ptr<CellGcmDisplayInfo> gcm_buffers{ vm::null };
|
||||
u32 tiles_addr;
|
||||
u32 ctxt_addr;
|
||||
CellGcmConfig current_config;
|
||||
CellGcmContextData current_context;
|
||||
gcmInfo gcm_info;
|
||||
};
|
||||
|
||||
u64 system_mode = 0;
|
||||
u32 local_size = 0;
|
||||
u32 local_addr = 0;
|
||||
u64 system_mode = 0;
|
||||
|
||||
CellGcmConfig current_config;
|
||||
CellGcmContextData current_context;
|
||||
gcmInfo gcm_info;
|
||||
|
||||
u32 map_offset_addr = 0;
|
||||
u32 map_offset_pos = 0;
|
||||
|
||||
// Auxiliary functions
|
||||
|
||||
@@ -82,7 +85,12 @@ void InitOffsetTable()
|
||||
u32 cellGcmGetLabelAddress(u8 index)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetLabelAddress(index=%d)", index);
|
||||
return gcm_info.label_addr + 0x10 * index;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
|
||||
return m_config->gcm_info.label_addr + 0x10 * index;
|
||||
}
|
||||
|
||||
vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 location)
|
||||
@@ -94,7 +102,7 @@ vm::ptr<CellGcmReportData> cellGcmGetReportDataAddressLocation(u32 index, u32 lo
|
||||
cellGcmSys.error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index);
|
||||
return vm::null;
|
||||
}
|
||||
return vm::ptr<CellGcmReportData>::make(0xC0000000 + index * 0x10);
|
||||
return vm::ptr<CellGcmReportData>::make(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
if (location == CELL_GCM_LOCATION_MAIN) {
|
||||
@@ -117,7 +125,7 @@ u64 cellGcmGetTimeStamp(u32 index)
|
||||
cellGcmSys.error("cellGcmGetTimeStamp: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return vm::read64(0xC0000000 + index * 0x10);
|
||||
return vm::read64(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
u32 cellGcmGetCurrentField()
|
||||
@@ -144,7 +152,7 @@ u32 cellGcmGetNotifyDataAddress(u32 index)
|
||||
*/
|
||||
vm::ptr<CellGcmReportData> _cellGcmFunc12()
|
||||
{
|
||||
return vm::ptr<CellGcmReportData>::make(0xC0000000); // TODO
|
||||
return vm::ptr<CellGcmReportData>::make(0x40301400); // TODO
|
||||
}
|
||||
|
||||
u32 cellGcmGetReport(u32 type, u32 index)
|
||||
@@ -172,7 +180,7 @@ u32 cellGcmGetReportDataAddress(u32 index)
|
||||
cellGcmSys.error("cellGcmGetReportDataAddress: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return 0xC0000000 + index * 0x10;
|
||||
return 0x40301400 + index * 0x10;
|
||||
}
|
||||
|
||||
u32 cellGcmGetReportDataLocation(u32 index, u32 location)
|
||||
@@ -192,7 +200,7 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
|
||||
cellGcmSys.error("cellGcmGetTimeStampLocation: Wrong local index (%d)", index);
|
||||
return 0;
|
||||
}
|
||||
return vm::read64(0xC0000000 + index * 0x10);
|
||||
return vm::read64(0x40301400 + index * 0x10);
|
||||
}
|
||||
|
||||
if (location == CELL_GCM_LOCATION_MAIN) {
|
||||
@@ -214,20 +222,31 @@ u64 cellGcmGetTimeStampLocation(u32 index, u32 location)
|
||||
u32 cellGcmGetControlRegister()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetControlRegister()");
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
return gcm_info.control_addr;
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.control_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDefaultCommandWordSize()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetDefaultCommandWordSize()");
|
||||
return gcm_info.command_size;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.command_size;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDefaultSegmentWordSize()
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetDefaultSegmentWordSize()");
|
||||
return gcm_info.segment_size;
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_info.segment_size;
|
||||
}
|
||||
|
||||
s32 cellGcmInitDefaultFifoMode(s32 mode)
|
||||
@@ -280,8 +299,10 @@ s32 cellGcmBindZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
void cellGcmGetConfiguration(vm::ptr<CellGcmConfig> config)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetConfiguration(config=*0x%x)", config);
|
||||
const auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
|
||||
*config = current_config;
|
||||
if (m_config)
|
||||
*config = m_config->current_config;
|
||||
}
|
||||
|
||||
u32 cellGcmGetFlipStatus()
|
||||
@@ -297,9 +318,9 @@ u32 cellGcmGetTiledPitchSize(u32 size)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmGetTiledPitchSize(size=%d)", size);
|
||||
|
||||
for (size_t i=0; i < sizeof(tiled_pitches) / sizeof(tiled_pitches[0]) - 1; i++) {
|
||||
if (tiled_pitches[i] < size && size <= tiled_pitches[i+1]) {
|
||||
return tiled_pitches[i+1];
|
||||
for (size_t i = 0; i < sizeof(tiled_pitches) / sizeof(tiled_pitches[0]) - 1; i++) {
|
||||
if (tiled_pitches[i] < size && size <= tiled_pitches[i + 1]) {
|
||||
return tiled_pitches[i + 1];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -324,8 +345,12 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
{
|
||||
cellGcmSys.warning("_cellGcmInitBody(context=**0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context, cmdSize, ioSize, ioAddress);
|
||||
|
||||
current_config.ioAddress = 0;
|
||||
current_config.localAddress = 0;
|
||||
auto m_config = fxm::make<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
m_config->current_config.ioAddress = 0;
|
||||
m_config->current_config.localAddress = 0;
|
||||
local_size = 0;
|
||||
local_addr = 0;
|
||||
|
||||
@@ -356,33 +381,42 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
map_offset_addr = 0;
|
||||
map_offset_pos = 0;
|
||||
current_config.ioSize = ioSize;
|
||||
current_config.ioAddress = ioAddress;
|
||||
current_config.localSize = local_size;
|
||||
current_config.localAddress = local_addr;
|
||||
current_config.memoryFrequency = 650000000;
|
||||
current_config.coreFrequency = 500000000;
|
||||
m_config->current_config.ioSize = ioSize;
|
||||
m_config->current_config.ioAddress = ioAddress;
|
||||
m_config->current_config.localSize = local_size;
|
||||
m_config->current_config.localAddress = local_addr;
|
||||
m_config->current_config.memoryFrequency = 650000000;
|
||||
m_config->current_config.coreFrequency = 500000000;
|
||||
|
||||
// Create contexts
|
||||
|
||||
u32 addr = vm::falloc(0x40000000, 0x400000);
|
||||
if (addr == 0 || addr != 0x40000000)
|
||||
fmt::throw_exception("Failed to alloc 0x40000000.");
|
||||
|
||||
g_defaultCommandBufferBegin = ioAddress;
|
||||
g_defaultCommandBufferFragmentCount = cmdSize / (32 * 1024);
|
||||
|
||||
gcm_info.context_addr = vm::alloc(0x1000, vm::main);
|
||||
gcm_info.control_addr = vm::alloc(0x1000, vm::main);
|
||||
gcm_info.label_addr = vm::alloc(0x1000, vm::main); // ???
|
||||
m_config->gcm_info.context_addr = 0x40000000;
|
||||
m_config->gcm_info.control_addr = 0x40100000;
|
||||
m_config->gcm_info.label_addr = 0x40300000;
|
||||
|
||||
current_context.begin.set(g_defaultCommandBufferBegin + 4096); // 4 kb reserved at the beginning
|
||||
current_context.end.set(g_defaultCommandBufferBegin + 32 * 1024 - 4); // 4b at the end for jump
|
||||
current_context.current = current_context.begin;
|
||||
current_context.callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(cellGcmCallback));
|
||||
m_config->current_context.begin.set(g_defaultCommandBufferBegin + 4096); // 4 kb reserved at the beginning
|
||||
m_config->current_context.end.set(g_defaultCommandBufferBegin + 32 * 1024 - 4); // 4b at the end for jump
|
||||
m_config->current_context.current = m_config->current_context.begin;
|
||||
m_config->current_context.callback.set(ppu_function_manager::addr + 8 * FIND_FUNC(cellGcmCallback));
|
||||
|
||||
vm::_ref<CellGcmContextData>(gcm_info.context_addr) = current_context;
|
||||
context->set(gcm_info.context_addr);
|
||||
m_config->ctxt_addr = context.addr();
|
||||
m_config->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
|
||||
m_config->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
m_config->tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
|
||||
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(gcm_info.control_addr);
|
||||
vm::_ref<CellGcmContextData>(m_config->gcm_info.context_addr) = m_config->current_context;
|
||||
context->set(m_config->gcm_info.context_addr);
|
||||
|
||||
// 0x40 is to offset CellGcmControl from RsxDmaControl
|
||||
m_config->gcm_info.control_addr += 0x40;
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr);
|
||||
ctrl.put = 0;
|
||||
ctrl.get = 0;
|
||||
ctrl.ref = -1;
|
||||
@@ -390,15 +424,10 @@ s32 _cellGcmInitBody(vm::pptr<CellGcmContextData> context, u32 cmdSize, u32 ioSi
|
||||
const auto render = fxm::get<GSRender>();
|
||||
render->intr_thread = idm::make_ptr<ppu_thread>("_gcm_intr_thread", 1, 0x4000);
|
||||
render->intr_thread->run();
|
||||
render->ctxt_addr = context.addr();
|
||||
render->gcm_buffers.set(vm::alloc(sizeof(CellGcmDisplayInfo) * 8, vm::main));
|
||||
render->zculls_addr = vm::alloc(sizeof(CellGcmZcullInfo) * 8, vm::main);
|
||||
render->tiles_addr = vm::alloc(sizeof(CellGcmTileInfo) * 15, vm::main);
|
||||
render->gcm_buffers_count = 0;
|
||||
render->gcm_current_buffer = 0;
|
||||
render->main_mem_addr = 0;
|
||||
render->label_addr = gcm_info.label_addr;
|
||||
render->init(g_defaultCommandBufferBegin, cmdSize, gcm_info.control_addr, local_addr);
|
||||
render->isHLE = true;
|
||||
render->label_addr = m_config->gcm_info.label_addr;
|
||||
render->init(ioAddress, ioSize, m_config->gcm_info.control_addr - 0x40, local_addr);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -431,6 +460,10 @@ s32 cellGcmSetDisplayBuffer(u8 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetDisplayBuffer(id=0x%x, offset=0x%x, pitch=%d, width=%d, height=%d)", id, offset, width ? pitch / width : pitch, width, height);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (id > 7)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetDisplayBuffer: CELL_GCM_ERROR_FAILURE");
|
||||
@@ -439,16 +472,21 @@ s32 cellGcmSetDisplayBuffer(u8 id, u32 offset, u32 pitch, u32 width, u32 height)
|
||||
|
||||
const auto render = fxm::get<GSRender>();
|
||||
|
||||
auto buffers = render->gcm_buffers;
|
||||
auto buffers = render->display_buffers;
|
||||
|
||||
buffers[id].offset = offset;
|
||||
buffers[id].pitch = pitch;
|
||||
buffers[id].width = width;
|
||||
buffers[id].height = height;
|
||||
|
||||
if (id + 1 > render->gcm_buffers_count)
|
||||
m_config->gcm_buffers[id].offset = offset;
|
||||
m_config->gcm_buffers[id].pitch = pitch;
|
||||
m_config->gcm_buffers[id].width = width;
|
||||
m_config->gcm_buffers[id].height = height;
|
||||
|
||||
if (id + 1u > render->display_buffers_count)
|
||||
{
|
||||
render->gcm_buffers_count = id + 1;
|
||||
render->display_buffers_count = id + 1;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
@@ -465,17 +503,7 @@ void cellGcmSetFlipMode(u32 mode)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetFlipMode(mode=%d)", mode);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case CELL_GCM_DISPLAY_HSYNC:
|
||||
case CELL_GCM_DISPLAY_VSYNC:
|
||||
case CELL_GCM_DISPLAY_HSYNC_WITH_NOISE:
|
||||
fxm::get<GSRender>()->flip_mode = mode;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fxm::get<GSRender>()->requested_vsync.store(mode == CELL_GCM_DISPLAY_VSYNC);
|
||||
}
|
||||
|
||||
void cellGcmSetFlipStatus()
|
||||
@@ -488,6 +516,9 @@ void cellGcmSetFlipStatus()
|
||||
s32 cellGcmSetPrepareFlip(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctxt, u32 id)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetPrepareFlip(ctxt=*0x%x, id=0x%x)", ctxt, id);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (id > 7)
|
||||
{
|
||||
@@ -506,9 +537,9 @@ s32 cellGcmSetPrepareFlip(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctxt, u32
|
||||
|
||||
const u32 cmd_size = rsx::make_command(ctxt->current, GCM_FLIP_COMMAND, { id });
|
||||
|
||||
if (ctxt.addr() == gcm_info.context_addr)
|
||||
if (ctxt.addr() == m_config->gcm_info.context_addr)
|
||||
{
|
||||
vm::_ref<CellGcmControl>(gcm_info.control_addr).put += cmd_size;
|
||||
vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr).put += cmd_size;
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -535,15 +566,12 @@ void cellGcmSetSecondVFrequency(u32 freq)
|
||||
switch (freq)
|
||||
{
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ:
|
||||
render->frequency_mode = freq;
|
||||
render->fps_limit = 59.94;
|
||||
break;
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT:
|
||||
render->frequency_mode = freq;
|
||||
cellGcmSys.todo("Unimplemented display frequency: Scanout");
|
||||
break;
|
||||
case CELL_GCM_DISPLAY_FREQUENCY_DISABLE:
|
||||
render->frequency_mode = freq;
|
||||
cellGcmSys.todo("Unimplemented display frequency: Disabled");
|
||||
break;
|
||||
default:
|
||||
@@ -557,6 +585,10 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
cellGcmSys.warning("cellGcmSetTileInfo(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||
index, location, offset, size, pitch, comp, base, bank);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
if (index >= rsx::limits::tiles_count || base >= 2048 || bank >= 4)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetTileInfo: CELL_GCM_ERROR_INVALID_VALUE");
|
||||
@@ -591,7 +623,7 @@ s32 cellGcmSetTileInfo(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u
|
||||
tile.base = base;
|
||||
tile.bank = bank;
|
||||
|
||||
vm::_ptr<CellGcmTileInfo>(render->tiles_addr)[index] = tile.pack();
|
||||
vm::_ptr<CellGcmTileInfo>(m_config->tiles_addr)[index] = tile.pack();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -624,7 +656,7 @@ void cellGcmSetWaitFlip(vm::ptr<CellGcmContextData> ctxt)
|
||||
s32 cellGcmSetWaitFlipUnsafe()
|
||||
{
|
||||
cellGcmSys.todo("cellGcmSetWaitFlipUnsafe()");
|
||||
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -633,6 +665,10 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
cellGcmSys.todo("cellGcmSetZcull(index=%d, offset=0x%x, width=%d, height=%d, cullStart=0x%x, zFormat=0x%x, aaFormat=0x%x, zCullDir=0x%x, zCullFormat=0x%x, sFunc=0x%x, sRef=0x%x, sMask=0x%x)",
|
||||
index, offset, width, height, cullStart, zFormat, aaFormat, zCullDir, zCullFormat, sFunc, sRef, sMask);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return;
|
||||
|
||||
if (index >= rsx::limits::zculls_count)
|
||||
{
|
||||
cellGcmSys.error("cellGcmSetZcull: CELL_GCM_ERROR_INVALID_VALUE");
|
||||
@@ -643,7 +679,7 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
|
||||
auto& zcull = render->zculls[index];
|
||||
zcull.offset = offset;
|
||||
zcull.width = width;
|
||||
zcull.width = width;
|
||||
zcull.height = height;
|
||||
zcull.cullStart = cullStart;
|
||||
zcull.zFormat = zFormat;
|
||||
@@ -654,7 +690,7 @@ void cellGcmSetZcull(u8 index, u32 offset, u32 width, u32 height, u32 cullStart,
|
||||
zcull.sRef = sRef;
|
||||
zcull.sMask = sMask;
|
||||
|
||||
vm::_ptr<CellGcmZcullInfo>(render->zculls_addr)[index] = zcull.pack();
|
||||
vm::_ptr<CellGcmZcullInfo>(m_config->zculls_addr)[index] = zcull.pack();
|
||||
}
|
||||
|
||||
s32 cellGcmUnbindTile(u8 index)
|
||||
@@ -690,26 +726,35 @@ s32 cellGcmUnbindZcull(u8 index)
|
||||
u32 cellGcmGetTileInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetTileInfo()");
|
||||
return fxm::get<GSRender>()->tiles_addr;
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->tiles_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetZcullInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetZcullInfo()");
|
||||
return fxm::get<GSRender>()->zculls_addr;
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->zculls_addr;
|
||||
}
|
||||
|
||||
u32 cellGcmGetDisplayInfo()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetDisplayInfo()");
|
||||
return fxm::get<GSRender>()->gcm_buffers.addr();
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return 0;
|
||||
return m_config->gcm_buffers.addr();
|
||||
}
|
||||
|
||||
s32 cellGcmGetCurrentDisplayBufferId(vm::ptr<u8> id)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmGetCurrentDisplayBufferId(id=*0x%x)", id);
|
||||
|
||||
if ((*id = fxm::get<GSRender>()->gcm_current_buffer) > UINT8_MAX)
|
||||
if ((*id = fxm::get<GSRender>()->current_display_buffer) > UINT8_MAX)
|
||||
{
|
||||
fmt::throw_exception("Unexpected" HERE);
|
||||
}
|
||||
@@ -876,7 +921,7 @@ s32 cellGcmIoOffsetToAddress(u32 ioOffset, vm::ptr<u32> address)
|
||||
|
||||
u32 realAddr;
|
||||
|
||||
if (!RSXIOMem.getRealAddr(ioOffset, realAddr))
|
||||
if (!RSXIOMem.getRealAddr(ioOffset, realAddr))
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
*address = realAddr;
|
||||
@@ -898,7 +943,6 @@ s32 gcmMapEaIoAddress(u32 ea, u32 io, u32 size, bool is_strict)
|
||||
{
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (io >> 20) + i;
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (ea >> 20) + i;
|
||||
render->strict_ordering[(io >> 20) + i] = is_strict;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -948,6 +992,7 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmMapMainMemory(ea=0x%x, size=0x%x, offset=*0x%x)", ea, size, offset);
|
||||
|
||||
if (size == 0) return CELL_OK;
|
||||
if ((ea & 0xFFFFF) || (size & 0xFFFFF)) return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
u32 io = RSXIOMem.Map(ea, size);
|
||||
@@ -962,7 +1007,6 @@ s32 cellGcmMapMainMemory(u32 ea, u32 size, vm::ptr<u32> offset)
|
||||
{
|
||||
offsetTable.ioAddress[(ea >> 20) + i] = (u16)((io >> 20) + i);
|
||||
offsetTable.eaAddress[(io >> 20) + i] = (u16)((ea >> 20) + i);
|
||||
render->strict_ordering[(io >> 20) + i] = false;
|
||||
}
|
||||
|
||||
*offset = io;
|
||||
@@ -1113,23 +1157,27 @@ s32 cellGcmSetCursorImageOffset(u32 offset)
|
||||
void cellGcmSetDefaultCommandBuffer()
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetDefaultCommandBuffer()");
|
||||
vm::write32(fxm::get<GSRender>()->ctxt_addr, gcm_info.context_addr);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (m_config)
|
||||
vm::write32(m_config->ctxt_addr, m_config->gcm_info.context_addr);
|
||||
}
|
||||
|
||||
s32 cellGcmSetDefaultCommandBufferAndSegmentWordSize(u32 bufferSize, u32 segmentSize)
|
||||
{
|
||||
cellGcmSys.warning("cellGcmSetDefaultCommandBufferAndSegmentWordSize(bufferSize=0x%x, segmentSize=0x%x)", bufferSize, segmentSize);
|
||||
|
||||
const auto& put = vm::_ref<CellGcmControl>(gcm_info.control_addr).put;
|
||||
const auto& get = vm::_ref<CellGcmControl>(gcm_info.control_addr).get;
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
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)
|
||||
{
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
gcm_info.command_size = bufferSize;
|
||||
gcm_info.segment_size = segmentSize;
|
||||
m_config->gcm_info.command_size = bufferSize;
|
||||
m_config->gcm_info.segment_size = segmentSize;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -1148,9 +1196,11 @@ s32 _cellGcmSetFlipCommand(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctx, u32
|
||||
s32 _cellGcmSetFlipCommandWithWaitLabel(ppu_thread& ppu, vm::ptr<CellGcmContextData> ctx, u32 id, u32 label_index, u32 label_value)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmSetFlipCommandWithWaitLabel(ctx=*0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", ctx, id, label_index, label_value);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
s32 res = cellGcmSetPrepareFlip(ppu, ctx, id);
|
||||
vm::write32(gcm_info.label_addr + 0x10 * label_index, label_value);
|
||||
vm::write32(m_config->gcm_info.label_addr + 0x10 * label_index, label_value);
|
||||
return res < 0 ? CELL_GCM_ERROR_FAILURE : CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1159,6 +1209,10 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
cellGcmSys.warning("cellGcmSetTile(index=%d, location=%d, offset=%d, size=%d, pitch=%d, comp=%d, base=%d, bank=%d)",
|
||||
index, location, offset, size, pitch, comp, base, bank);
|
||||
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
// Copied form cellGcmSetTileInfo
|
||||
if (index >= rsx::limits::tiles_count || base >= 2048 || bank >= 4)
|
||||
{
|
||||
@@ -1194,7 +1248,7 @@ s32 cellGcmSetTile(u8 index, u8 location, u32 offset, u32 size, u32 pitch, u8 co
|
||||
tile.base = base;
|
||||
tile.bank = bank;
|
||||
|
||||
vm::_ptr<CellGcmTileInfo>(render->tiles_addr)[index] = tile.pack();
|
||||
vm::_ptr<CellGcmTileInfo>(m_config->tiles_addr)[index] = tile.pack();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -1286,8 +1340,11 @@ static bool isInCommandBufferExcept(u32 getPos, u32 bufferBegin, u32 bufferEnd)
|
||||
s32 cellGcmCallback(ppu_thread& ppu, vm::ptr<CellGcmContextData> context, u32 count)
|
||||
{
|
||||
cellGcmSys.trace("cellGcmCallback(context=*0x%x, count=0x%x)", context, count);
|
||||
auto m_config = fxm::get<CellGcmSysConfig>();
|
||||
if (!m_config)
|
||||
return CELL_GCM_ERROR_FAILURE;
|
||||
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(gcm_info.control_addr);
|
||||
auto& ctrl = vm::_ref<CellGcmControl>(m_config->gcm_info.control_addr);
|
||||
|
||||
// Flush command buffer (ie allow RSX to read up to context->current)
|
||||
ctrl.put.exchange(getOffsetFromAddress(context->current.addr()));
|
||||
@@ -1428,4 +1485,4 @@ DECLARE(ppu_module_manager::cellGcmSys)("cellGcmSys", []()
|
||||
|
||||
// Special
|
||||
REG_FUNC(cellGcmSys, cellGcmCallback).flags = MFF_HIDDEN;
|
||||
});
|
||||
});
|
||||
@@ -65,6 +65,12 @@ s32 cellHttpSetProxy()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpGetCookie()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpGetProxy()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
@@ -317,6 +323,24 @@ s32 cellHttpClientSetConnectionWaitStatus()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientGetConnectionWaitStatus()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientSetConnectionWaitTimeout()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientGetConnectionWaitTimeout()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientSetRecvTimeout()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
@@ -641,6 +665,18 @@ s32 cellHttpTransactionGetSslId()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientSetMinSslVersion()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientGetMinSslVersion()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellHttpClientSetSslVersion()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellHttp);
|
||||
@@ -671,6 +707,7 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []()
|
||||
REG_FUNC(cellHttp, cellHttpsInit);
|
||||
REG_FUNC(cellHttp, cellHttpsEnd);
|
||||
REG_FUNC(cellHttp, cellHttpSetProxy);
|
||||
REG_FUNC(cellHttp, cellHttpGetCookie);
|
||||
REG_FUNC(cellHttp, cellHttpGetProxy);
|
||||
|
||||
REG_FUNC(cellHttp, cellHttpInitCookie);
|
||||
@@ -719,7 +756,10 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []()
|
||||
REG_FUNC(cellHttp, cellHttpClientPollConnections);
|
||||
|
||||
REG_FUNC(cellHttp, cellHttpClientSetConnectionStateCallback);
|
||||
REG_FUNC(cellHttp, cellHttpClientGetConnectionWaitStatus);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetConnectionWaitStatus);
|
||||
REG_FUNC(cellHttp, cellHttpClientGetConnectionWaitTimeout);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetConnectionWaitTimeout);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetRecvTimeout);
|
||||
REG_FUNC(cellHttp, cellHttpClientGetRecvTimeout);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetSendTimeout);
|
||||
@@ -781,6 +821,8 @@ DECLARE(ppu_module_manager::cellHttp)("cellHttp", []()
|
||||
REG_FUNC(cellHttp, cellHttpTransactionGetSslVersion);
|
||||
REG_FUNC(cellHttp, cellHttpTransactionGetSslId);
|
||||
|
||||
REG_FUNC(cellHttp, cellHttpClientSetMinSslVersion);
|
||||
REG_FUNC(cellHttp, cellHttpClientGetMinSslVersion);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetSslVersion);
|
||||
REG_FUNC(cellHttp, cellHttpClientGetSslVersion);
|
||||
REG_FUNC(cellHttp, cellHttpClientSetSslIdDestroyCallback);
|
||||
|
||||
@@ -161,7 +161,7 @@ bool _L10nCodeParse(s32 code, HostCode& retCode)
|
||||
#ifdef _MSC_VER
|
||||
|
||||
// Use code page to transform std::string to std::wstring.
|
||||
s32 _OEM2Wide(HostCode oem_code, const std::string src, std::wstring& dst)
|
||||
s32 _OEM2Wide(HostCode oem_code, const std::string& src, std::wstring& dst)
|
||||
{
|
||||
//Such length returned should include the '\0' character.
|
||||
s32 length = MultiByteToWideChar(oem_code, 0, src.c_str(), -1, NULL, 0);
|
||||
@@ -178,7 +178,7 @@ s32 _OEM2Wide(HostCode oem_code, const std::string src, std::wstring& dst)
|
||||
}
|
||||
|
||||
// Use Code page to transform std::wstring to std::string.
|
||||
s32 _Wide2OEM(HostCode oem_code, const std::wstring src, std::string& dst)
|
||||
s32 _Wide2OEM(HostCode oem_code, const std::wstring& src, std::string& dst)
|
||||
{
|
||||
//Such length returned should include the '\0' character.
|
||||
s32 length = WideCharToMultiByte(oem_code, 0, src.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
@@ -195,7 +195,7 @@ s32 _Wide2OEM(HostCode oem_code, const std::wstring src, std::string& dst)
|
||||
}
|
||||
|
||||
// Convert Codepage to Codepage (all char*)
|
||||
std::string _OemToOem(HostCode src_code, HostCode dst_code, const std::string str)
|
||||
std::string _OemToOem(HostCode src_code, HostCode dst_code, const std::string& str)
|
||||
{
|
||||
std::wstring wide; std::string result;
|
||||
_OEM2Wide(src_code, str, wide);
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
|
||||
virtual ~MsgDialogBase();
|
||||
virtual void Create(const std::string& msg) = 0;
|
||||
virtual void CreateOsk(const std::string& msg, char16_t* osk_text) = 0;
|
||||
virtual void CreateOsk(const std::string& msg, char16_t* osk_text, u32 charlimit) = 0;
|
||||
virtual void ProgressBarSetMsg(u32 progressBarIndex, const std::string& msg) = 0;
|
||||
virtual void ProgressBarReset(u32 progressBarIndex) = 0;
|
||||
virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0;
|
||||
|
||||
@@ -202,6 +202,54 @@ error_code cellNetCtlGetNatInfo(vm::ptr<CellNetCtlNatInfo> natInfo)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlAddHandlerGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlAddHandlerGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlConnectGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlConnectGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlDelHandlerGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlDelHandlerGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlDisconnectGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlDisconnectGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetInfoGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetInfoGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetScanInfoGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetScanInfoGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlGetStateGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlGetStateGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellNetCtlScanGameInt()
|
||||
{
|
||||
cellNetCtl.todo("cellNetCtlScanGameInt()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellGameUpdateInit()
|
||||
{
|
||||
cellNetCtl.todo("cellGameUpdateInit()");
|
||||
@@ -274,6 +322,15 @@ DECLARE(ppu_module_manager::cellNetCtl)("cellNetCtl", []()
|
||||
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetNatInfo);
|
||||
|
||||
REG_FUNC(cellNetCtl, cellNetCtlAddHandlerGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlConnectGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlDelHandlerGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlDisconnectGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetInfoGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetScanInfoGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlGetStateGameInt);
|
||||
REG_FUNC(cellNetCtl, cellNetCtlScanGameInt);
|
||||
|
||||
REG_FUNC(cellNetCtl, cellGameUpdateInit);
|
||||
REG_FUNC(cellNetCtl, cellGameUpdateTerm);
|
||||
|
||||
|
||||
@@ -14,14 +14,21 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
||||
{
|
||||
cellOskDialog.warning("cellOskDialogLoadAsync(container=0x%x, dialogParam=*0x%x, inputFieldInfo=*0x%x)", container, dialogParam, inputFieldInfo);
|
||||
|
||||
u32 maxLength = (inputFieldInfo->limit_length >= 512) ? 511 : (u32)inputFieldInfo->limit_length;
|
||||
|
||||
std::memset(s_osk_text, 0, sizeof(s_osk_text));
|
||||
|
||||
if (inputFieldInfo->init_text.addr() != 0)
|
||||
for (u32 i = 0; (i < maxLength) && (inputFieldInfo->init_text[i] != 0); i++)
|
||||
s_osk_text[i] = inputFieldInfo->init_text[i];
|
||||
|
||||
const auto osk = Emu.GetCallbacks().get_msg_dialog();
|
||||
bool result = false;
|
||||
|
||||
osk->on_close = [&](s32 status)
|
||||
{
|
||||
sysutil_send_system_cmd(status == CELL_MSGDIALOG_BUTTON_OK ? CELL_SYSUTIL_OSKDIALOG_FINISHED : CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
if (status != CELL_MSGDIALOG_BUTTON_OK) sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_INPUT_CANCELED, 0);
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_FINISHED, 0);
|
||||
result = true;
|
||||
};
|
||||
|
||||
@@ -32,7 +39,7 @@ s32 cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dialogPara
|
||||
|
||||
Emu.CallAfter([&]()
|
||||
{
|
||||
osk->CreateOsk("On Screen Keyboard", s_osk_text);
|
||||
osk->CreateOsk("On Screen Keyboard", s_osk_text, maxLength);
|
||||
});
|
||||
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
@@ -141,6 +148,12 @@ s32 cellOskDialogExtRegisterKeyboardEventHookCallback(u16 hookEventMode, vm::ptr
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellOskDialogExtRegisterKeyboardEventHookCallbackEx(u16 hookEventMode, vm::ptr<cellOskDialogHardwareKeyboardEventHookCallback> pCallback)
|
||||
{
|
||||
cellOskDialog.todo("cellOskDialogExtRegisterKeyboardEventHookCallbackEx(hookEventMode=%u, pCallback=*0x%x)", hookEventMode, pCallback);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellOskDialogExtAddJapaneseOptionDictionary(vm::cpptr<char> filePath)
|
||||
{
|
||||
cellOskDialog.todo("cellOskDialogExtAddJapaneseOptionDictionary(filePath=**0x%0x)", filePath);
|
||||
@@ -247,6 +260,7 @@ DECLARE(ppu_module_manager::cellOskDialog)("cellOskExtUtility", []()
|
||||
{
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtInputDeviceUnlock);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtRegisterKeyboardEventHookCallback);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtRegisterKeyboardEventHookCallbackEx);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtAddJapaneseOptionDictionary);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtEnableClipboard);
|
||||
REG_FUNC(cellOskExtUtility, cellOskDialogExtSendFinishMessage);
|
||||
|
||||
@@ -248,7 +248,7 @@ s32 cellPadGetData(u32 port_no, vm::ptr<CellPadData> data)
|
||||
}
|
||||
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) & 0xF;
|
||||
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;
|
||||
|
||||
@@ -1,41 +1,90 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
logs::channel cellRec("cellRec");
|
||||
|
||||
s32 cellRecOpen()
|
||||
struct CellRecSpursParam
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
vm::bptr<struct CellSpurs> pSpurs;
|
||||
be_t<s32> spu_usage_rate;
|
||||
u8 priority[8];
|
||||
};
|
||||
|
||||
struct CellRecOption
|
||||
{
|
||||
be_t<s32> option;
|
||||
union
|
||||
{
|
||||
be_t<s32> ppu_thread_priority;
|
||||
be_t<s32> spu_thread_priority;
|
||||
be_t<s32> capture_priority;
|
||||
be_t<s32> use_system_spu;
|
||||
be_t<s32> fit_to_youtube;
|
||||
be_t<s32> xmb_bgm;
|
||||
be_t<s32> mpeg4_fast_encode;
|
||||
be_t<u32> ring_sec;
|
||||
be_t<s32> video_input;
|
||||
be_t<s32> audio_input;
|
||||
be_t<s32> audio_input_mix_vol;
|
||||
be_t<s32> reduce_memsize;
|
||||
be_t<s32> show_xmb;
|
||||
vm::bptr<char> metadata_filename;
|
||||
vm::bptr<CellRecSpursParam> pSpursParam;
|
||||
be_t<u64> dummy;
|
||||
} value;
|
||||
};
|
||||
|
||||
struct CellRecParam
|
||||
{
|
||||
be_t<s32> videoFmt;
|
||||
be_t<s32> audioFmt;
|
||||
be_t<s32> numOfOpt;
|
||||
vm::bptr<CellRecOption> pOpt;
|
||||
};
|
||||
|
||||
using CellRecCallback = void(s32 recStatus, s32 recError, vm::ptr<void> userdata);
|
||||
|
||||
s32 cellRecOpen(vm::cptr<char> pDirName, vm::cptr<char> pFileName, vm::cptr<CellRecParam> pParam, u32 container, vm::ptr<CellRecCallback> cb, vm::ptr<void> cbUserData)
|
||||
{
|
||||
cellRec.todo("cellRecOpen(pDirName=%s, pFileName=%s, pParam=*0x%x, container=0x%x, cb=*0x%x, cbUserData=*0x%x)", pDirName, pFileName, pParam, container, cb, cbUserData);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecClose()
|
||||
s32 cellRecClose(s32 isDiscard)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecClose(isDiscard=0x%x)", isDiscard);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecGetInfo()
|
||||
void cellRecGetInfo(s32 info, vm::ptr<u64> pValue)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecGetInfo(info=0x%x, pValue=*0x%x)", info, pValue);
|
||||
}
|
||||
|
||||
s32 cellRecStop()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecStop()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecStart()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecStart()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellRecQueryMemSize()
|
||||
u32 cellRecQueryMemSize(vm::cptr<CellRecParam> pParam)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecQueryMemSize(pParam=*0x%x)", pParam);
|
||||
return 1 * 1024 * 1024; // dummy memory size
|
||||
}
|
||||
|
||||
s32 cellRecSetInfo()
|
||||
s32 cellRecSetInfo(s32 setInfo, u64 value)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellRec.todo("cellRecSetInfo(setInfo=0x%x, value=0x%x)", setInfo, value);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -123,8 +123,8 @@ s32 cellRescGetFlipStatus()
|
||||
|
||||
s32 cellRescGetRegisterCount()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc.todo("cellRescGetRegisterCount()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
u64 cellRescGetLastFlipTime()
|
||||
@@ -134,10 +134,9 @@ u64 cellRescGetLastFlipTime()
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 cellRescSetRegisterCount()
|
||||
void cellRescSetRegisterCount(s32 regCount)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellResc);
|
||||
return CELL_OK;
|
||||
cellResc.todo("cellRescSetRegisterCount(regCount=0x%x)", regCount);
|
||||
}
|
||||
|
||||
void cellRescSetVBlankHandler(vm::ptr<void(u32)> handler)
|
||||
|
||||
@@ -248,12 +248,126 @@ s32 cellSailRecorderCancel()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderRegisterComposer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderUnregisterComposer()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailRecorderDumpImage()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerInitialize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerFinalize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetStreamParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsAudioParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsUserParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsVideoParameter()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerGetEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerTryGetEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsAudioAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsUserAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerReleaseEsVideoAu()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerNotifyCallCompleted()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSailComposerNotifySessionError()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSailRec);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSailRec)("cellSailRec", []()
|
||||
{
|
||||
static ppu_static_module cellMp4("cellMp4");
|
||||
@@ -301,6 +415,26 @@ DECLARE(ppu_module_manager::cellSailRec)("cellSailRec", []()
|
||||
REG_FUNC(cellSailRec, cellSailRecorderStart);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderStop);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderCancel);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderRegisterComposer);
|
||||
REG_FUNC(cellSailRec, cellSailRecorderUnregisterComposer);
|
||||
|
||||
REG_FUNC(cellSailRec, cellSailRecorderDumpImage);
|
||||
|
||||
REG_FUNC(cellSailRec, cellSailComposerInitialize);
|
||||
REG_FUNC(cellSailRec, cellSailComposerFinalize);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetStreamParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsAudioParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsUserParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsVideoParameter);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerGetEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerTryGetEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsAudioAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsUserAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerReleaseEsVideoAu);
|
||||
REG_FUNC(cellSailRec, cellSailComposerNotifyCallCompleted);
|
||||
REG_FUNC(cellSailRec, cellSailComposerNotifySessionError);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
#include "Emu/Cell/Modules/cellSysutil.h"
|
||||
|
||||
#include "cellSaveData.h"
|
||||
|
||||
@@ -63,7 +64,6 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
PFuncFile funcFile, u32 container, u32 unknown, vm::ptr<void> userdata, u32 userId, PFuncDone funcDone)
|
||||
{
|
||||
// TODO: check arguments
|
||||
|
||||
std::unique_lock<std::mutex> lock(g_savedata_mutex, std::try_to_lock);
|
||||
|
||||
if (!lock)
|
||||
@@ -82,6 +82,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
vm::ptr<CellSaveDataFileGet> fileGet = g_savedata_context.ptr(&savedata_context::fileGet);
|
||||
vm::ptr<CellSaveDataFileSet> fileSet = g_savedata_context.ptr(&savedata_context::fileSet);
|
||||
|
||||
//TODO: get current user ID
|
||||
// userId(0) = CELL_SYSUTIL_USERID_CURRENT
|
||||
// path of the specified user (00000001 by default)
|
||||
const std::string& base_dir = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/", userId ? userId : 1u));
|
||||
|
||||
@@ -100,6 +102,7 @@ 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))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
@@ -211,13 +214,15 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: display dialog
|
||||
cellSaveData.warning("savedata_op(): funcList returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
// if the callback has returned ok, lets return OK.
|
||||
// typically used at game launch when no list is actually required.
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
// CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM is only valid for funcFile and funcDone
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -236,6 +241,16 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return true;
|
||||
}), save_entries.end());
|
||||
|
||||
// Add any new data (not currently supported by the UI)
|
||||
//if (listSet->newData)
|
||||
//{
|
||||
// SaveDataEntry *_saveDataEntry = new SaveDataEntry();
|
||||
// _saveDataEntry->dirName = listSet->newData->dirName.get_ptr();
|
||||
|
||||
// save_entry.dirName = listSet->newData->dirName.get_ptr();
|
||||
// save_entries.emplace_back(*_saveDataEntry);
|
||||
//}
|
||||
|
||||
// Focus save data
|
||||
s32 focused = -1;
|
||||
|
||||
@@ -296,6 +311,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
case CELL_SAVEDATA_FOCUSPOS_NEWDATA:
|
||||
{
|
||||
//TODO: If adding the new data to the save_entries vector
|
||||
// to be displayed in the save mangaer UI, it should be focused here
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -339,8 +356,19 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
// Fixed Callback
|
||||
funcFixed(ppu, result, listGet, fixedSet);
|
||||
|
||||
// skip all following steps if OK_LAST
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (result->result < 0)
|
||||
{
|
||||
//TODO: Show msgDialog if required
|
||||
// depends on fixedSet->option
|
||||
// 0 = none
|
||||
// 1 = skip confirmation dialog
|
||||
|
||||
cellSaveData.warning("savedata_op(): funcFixed returned < 0.");
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
@@ -363,10 +391,7 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
{
|
||||
save_entry.dirName = fixedSet->dirName.get_ptr();
|
||||
}
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (selected >= 0)
|
||||
@@ -479,6 +504,11 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return CELL_SAVEDATA_ERROR_CBRESULT;
|
||||
}
|
||||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (statSet->setParam)
|
||||
{
|
||||
// Update PARAM.SFO
|
||||
@@ -498,18 +528,20 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
{ "TITLE", psf::string(128, statSet->setParam->title) },
|
||||
});
|
||||
}
|
||||
else if (psf.empty())
|
||||
{
|
||||
// setParam is NULL for new savedata: abort operation
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
//else if (psf.empty())
|
||||
//{
|
||||
// // setParam is specified if something required updating.
|
||||
// // Do not exit. Recreate mode will handle the rest
|
||||
// //return CELL_OK;
|
||||
//}
|
||||
|
||||
switch (const u32 mode = statSet->reCreateMode & 0xffff)
|
||||
{
|
||||
case CELL_SAVEDATA_RECREATE_NO:
|
||||
{
|
||||
cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
//CELL_SAVEDATA_RECREATE_NO = overwrite and let the user know, not data is corrupt.
|
||||
//cellSaveData.error("Savedata %s considered broken", save_entry.dirName);
|
||||
//TODO: if this is a save, and it's not auto, then show a dialog
|
||||
// fallthrough
|
||||
}
|
||||
|
||||
@@ -521,7 +553,8 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
case CELL_SAVEDATA_RECREATE_YES:
|
||||
case CELL_SAVEDATA_RECREATE_YES_RESET_OWNER:
|
||||
{
|
||||
// TODO?
|
||||
|
||||
// TODO: Only delete data, not owner info
|
||||
for (const auto& entry : fs::dir(dir_path))
|
||||
{
|
||||
if (!entry.is_directory)
|
||||
@@ -530,12 +563,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: probably not deleting owner info
|
||||
if (!statSet->setParam)
|
||||
{
|
||||
// Savedata deleted and setParam is NULL: delete directory and abort operation
|
||||
if (fs::remove_dir(dir_path)) cellSaveData.error("savedata_op(): savedata directory %s deleted", save_entry.dirName);
|
||||
|
||||
return CELL_OK;
|
||||
//return CELL_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -549,16 +583,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
}
|
||||
}
|
||||
|
||||
if ((result->result == CELL_SAVEDATA_CBRESULT_OK_LAST) || (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM))
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
// Create save directory if necessary
|
||||
if (psf.size() && save_entry.isNew && !fs::create_dir(dir_path))
|
||||
{
|
||||
// Let's ignore this error for now
|
||||
{
|
||||
cellSaveData.warning("savedata_op(): failed to create %s", dir_path);
|
||||
return CELL_SAVEDATA_ERROR_ACCESS_ERROR;
|
||||
}
|
||||
|
||||
// Enter the loop where the save files are read/created/deleted
|
||||
@@ -578,9 +609,13 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
|
||||
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
|
||||
{
|
||||
//todo: display user prompt
|
||||
break;
|
||||
}
|
||||
|
||||
//TODO: Show progress
|
||||
// if it's not an auto load/save
|
||||
|
||||
std::string file_path;
|
||||
|
||||
switch (const u32 type = fileSet->fileType)
|
||||
@@ -681,6 +716,57 @@ static NEVER_INLINE s32 savedata_op(ppu_thread& ppu, u32 operation, u32 version,
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 static NEVER_INLINE save_op_get_list_item(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB, u32 userId)
|
||||
{
|
||||
|
||||
//TODO: accurately get the current user
|
||||
if (userId == 0)
|
||||
{
|
||||
userId = 1u;
|
||||
}
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/%08u/savedata/%s/", userId, dirName.get_ptr()));
|
||||
std::string sfo = save_path + "PARAM.SFO";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
if (dir)
|
||||
{
|
||||
fs::stat_t dir_info{};
|
||||
if (!fs::stat(save_path, dir_info))
|
||||
{
|
||||
return CELL_SAVEDATA_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
// get file stats, namely directory
|
||||
strcpy_trunc(dir->dirName, dirName.get_ptr());
|
||||
dir->atime = dir_info.atime;
|
||||
dir->ctime = dir_info.ctime;
|
||||
dir->mtime = dir_info.mtime;
|
||||
}
|
||||
|
||||
if (bind)
|
||||
{
|
||||
//TODO: Set bind in accordance to any problems
|
||||
*bind = 0;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
// Functions
|
||||
s32 cellSaveDataListSave2(ppu_thread& ppu, u32 version, PSetList setList, PSetBuf setBuf, PFuncList funcList,
|
||||
PFuncStat funcStat, PFuncFile funcFile, u32 container, vm::ptr<void> userdata)
|
||||
@@ -949,27 +1035,8 @@ s32 cellSaveDataFixedExport(ppu_thread& ppu, vm::cptr<char> dirName, u32 maxSize
|
||||
s32 cellSaveDataGetListItem(vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB);
|
||||
|
||||
std::string save_path = vfs::get(fmt::format("/dev_hdd0/home/00000001/savedata/%s/", dirName.get_ptr()));
|
||||
std::string sfo = save_path + "param.sfo";
|
||||
|
||||
if (!fs::is_dir(save_path) && !fs::is_file(sfo))
|
||||
{
|
||||
cellSaveData.error("cellSaveDataGetListItem(): Savedata at %s does not exist", dirName);
|
||||
return CELL_SAVEDATA_ERROR_NODATA;
|
||||
}
|
||||
|
||||
auto psf = psf::load_object(fs::file(sfo));
|
||||
|
||||
if (sysFileParam)
|
||||
{
|
||||
strcpy_trunc(sysFileParam->listParam, psf.at("SAVEDATA_LIST_PARAM").as_string());
|
||||
strcpy_trunc(sysFileParam->title, psf.at("TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->subTitle, psf.at("SUB_TITLE").as_string());
|
||||
strcpy_trunc(sysFileParam->detail, psf.at("DETAIL").as_string());
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, 0);
|
||||
}
|
||||
|
||||
s32 cellSaveDataUserListDelete(ppu_thread& ppu, u32 userId, PSetList setList, PSetBuf setBuf, PFuncList funcList, PFuncDone funcDone, u32 container, vm::ptr<void> userdata)
|
||||
@@ -1009,9 +1076,9 @@ s32 cellSaveDataUserFixedExport(ppu_thread& ppu, u32 userId, vm::cptr<char> dirN
|
||||
|
||||
s32 cellSaveDataUserGetListItem(u32 userId, vm::cptr<char> dirName, vm::ptr<CellSaveDataDirStat> dir, vm::ptr<CellSaveDataSystemFileParam> sysFileParam, vm::ptr<u32> bind, vm::ptr<u32> sizeKB)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSaveData);
|
||||
cellSaveData.warning("cellSavaDataGetListItem(dirName=%s, dir=*0x%x, sysFileParam=*0x%x, bind=*0x%x, sizeKB=*0x%x, userID=*0x%x)", dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
|
||||
return CELL_OK;
|
||||
return save_op_get_list_item(dirName, dir, sysFileParam, bind, sizeKB, userId);
|
||||
}
|
||||
|
||||
void cellSysutil_SaveData_init()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
||||
@@ -118,6 +118,12 @@ s32 cellSearchGetContentInfoDeveloperData()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSearchGetContentInfoSharable()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSearch);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSearchCancel()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSearch);
|
||||
@@ -150,6 +156,7 @@ DECLARE(ppu_module_manager::cellSearch)("cellSearchUtility", []()
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoPathMovieThumb);
|
||||
REG_FUNC(cellSearchUtility, cellSearchPrepareFile);
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoDeveloperData);
|
||||
REG_FUNC(cellSearchUtility, cellSearchGetContentInfoSharable);
|
||||
REG_FUNC(cellSearchUtility, cellSearchCancel);
|
||||
REG_FUNC(cellSearchUtility, cellSearchEnd);
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
logs::channel cellSpurs("cellSpurs");
|
||||
|
||||
s32 sys_spu_image_close(vm::ptr<sys_spu_image> img);
|
||||
error_code sys_spu_image_close(vm::ptr<sys_spu_image> img);
|
||||
|
||||
// TODO
|
||||
struct cell_error_t
|
||||
@@ -880,7 +880,7 @@ s32 _spurs::stop_event_helper(ppu_thread& ppu, vm::ptr<CellSpurs> spurs)
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
|
||||
if (sys_event_port_send(ppu, spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
if (sys_event_port_send(spurs->eventPort, 0, 1, 0) != CELL_OK)
|
||||
{
|
||||
return CELL_SPURS_CORE_ERROR_STAT;
|
||||
}
|
||||
@@ -2794,7 +2794,7 @@ s32 cellSpursEventFlagSet(ppu_thread& ppu, vm::ptr<CellSpursEventFlag> eventFlag
|
||||
// Signal the PPU thread to be woken up
|
||||
eventFlag->pendingRecvTaskEvents[ppuWaitSlot] = ppuEvents;
|
||||
|
||||
CHECK_SUCCESS(sys_event_port_send(ppu, eventFlag->eventPortId, 0, 0, 0));
|
||||
CHECK_SUCCESS(sys_event_port_send(eventFlag->eventPortId, 0, 0, 0));
|
||||
}
|
||||
|
||||
if (pendingRecv)
|
||||
|
||||
+38
-29
@@ -1,9 +1,9 @@
|
||||
#include "stdafx.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "cellSubdisplay.h"
|
||||
#include "cellSubDisplay.h"
|
||||
|
||||
logs::channel cellSubdisplay("cellSubdisplay");
|
||||
logs::channel cellSubDisplay("cellSubDisplay");
|
||||
|
||||
template<>
|
||||
void fmt_class_string<CellSubDisplayError>::format(std::string& out, u64 arg)
|
||||
@@ -28,51 +28,51 @@ void fmt_class_string<CellSubDisplayError>::format(std::string& out, u64 arg)
|
||||
|
||||
error_code cellSubDisplayInit(vm::ptr<CellSubDisplayParam> pParam, vm::ptr<CellSubDisplayHandler> func, vm::ptr<void> userdata, u32 container)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayInit(pParam=*0x%x, func=*0x%x, userdata=*0x%x, container=0x%x)", pParam, func, userdata, container);
|
||||
cellSubDisplay.todo("cellSubDisplayInit(pParam=*0x%x, func=*0x%x, userdata=*0x%x, container=0x%x)", pParam, func, userdata, container);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayEnd()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayEnd()");
|
||||
cellSubDisplay.todo("cellSubDisplayEnd()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetRequiredMemory(vm::ptr<CellSubDisplayParam> pParam)
|
||||
{
|
||||
cellSubdisplay.warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam);
|
||||
cellSubDisplay.warning("cellSubDisplayGetRequiredMemory(pParam=*0x%x)", pParam);
|
||||
|
||||
if (pParam->version == CELL_SUBDISPLAY_VERSION_0002)
|
||||
switch (pParam->version)
|
||||
{
|
||||
return not_an_error(CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return not_an_error(CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0001: return not_an_error(CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0002: return not_an_error(CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE);
|
||||
case CELL_SUBDISPLAY_VERSION_0003: return not_an_error(CELL_SUBDISPLAY_0003_MEMORY_CONTAINER_SIZE);
|
||||
}
|
||||
|
||||
return CELL_SUBDISPLAY_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayStart()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayStart()");
|
||||
cellSubDisplay.todo("cellSubDisplayStart()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayStop()
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayStop()");
|
||||
cellSubDisplay.todo("cellSubDisplayStop()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetVideoBuffer(s32 groupId, vm::pptr<void> ppVideoBuf, vm::ptr<u32> pSize)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetVideoBuffer(groupId=%d, ppVideoBuf=**0x%x, pSize=*0x%x)", groupId, ppVideoBuf, pSize);
|
||||
cellSubDisplay.todo("cellSubDisplayGetVideoBuffer(groupId=%d, ppVideoBuf=**0x%x, pSize=*0x%x)", groupId, ppVideoBuf, pSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayAudioOutBlocking(s32 groupId, vm::ptr<void> pvData, s32 samples)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayAudioOutBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
@@ -84,7 +84,7 @@ error_code cellSubDisplayAudioOutBlocking(s32 groupId, vm::ptr<void> pvData, s32
|
||||
|
||||
error_code cellSubDisplayAudioOutNonBlocking(s32 groupId, vm::ptr<void> pvData, s32 samples)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayAudioOutNonBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
cellSubDisplay.todo("cellSubDisplayAudioOutNonBlocking(groupId=%d, pvData=*0x%x, samples=%d)", groupId, pvData, samples);
|
||||
|
||||
if (samples % 1024)
|
||||
{
|
||||
@@ -96,34 +96,43 @@ error_code cellSubDisplayAudioOutNonBlocking(s32 groupId, vm::ptr<void> pvData,
|
||||
|
||||
error_code cellSubDisplayGetPeerNum(s32 groupId)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetPeerNum(groupId=%d)", groupId);
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerNum(groupId=%d)", groupId);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSubDisplayGetPeerList(s32 groupId, vm::ptr<CellSubDisplayPeerInfo> pInfo, vm::ptr<s32> pNum)
|
||||
{
|
||||
cellSubdisplay.todo("cellSubDisplayGetPeerList(groupId=%d, pInfo=*0x%x, pNum=*0x%x)", groupId, pInfo, pNum);
|
||||
cellSubDisplay.todo("cellSubDisplayGetPeerList(groupId=%d, pInfo=*0x%x, pNum=*0x%x)", groupId, pInfo, pNum);
|
||||
|
||||
*pNum = 0;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSubdisplay)("cellSubdisplay", []()
|
||||
error_code cellSubDisplayGetTouchInfo(s32 groupId, vm::ptr<CellSubDisplayTouchInfo> pTouchInfo, vm::ptr<s32> pNumTouchInfo)
|
||||
{
|
||||
cellSubDisplay.todo("cellSubDisplayGetTouchInfo(groupId=%d, pTouchInfo=*0x%x, pNumTouchInfo=*0x%x)", groupId, pTouchInfo, pNumTouchInfo);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::cellSubDisplay)("cellSubDisplay", []()
|
||||
{
|
||||
// Initialization / Termination Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayInit);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayEnd);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetRequiredMemory);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayStart);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayStop);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayInit);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayEnd);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetRequiredMemory);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayStart);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayStop);
|
||||
|
||||
// Data Setting Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetVideoBuffer);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayAudioOutBlocking);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayAudioOutNonBlocking);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetVideoBuffer);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayAudioOutBlocking);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayAudioOutNonBlocking);
|
||||
|
||||
// Peer Status Acquisition Functions
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetPeerNum);
|
||||
REG_FUNC(cellSubdisplay, cellSubDisplayGetPeerList);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetPeerNum);
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetPeerList);
|
||||
|
||||
//
|
||||
REG_FUNC(cellSubDisplay, cellSubDisplayGetTouchInfo);
|
||||
});
|
||||
@@ -23,9 +23,11 @@ enum
|
||||
CELL_SUBDISPLAY_STATUS_FATALERROR = 3,
|
||||
CELL_SUBDISPLAY_VERSION_0001 = 1,
|
||||
CELL_SUBDISPLAY_VERSION_0002 = 2,
|
||||
CELL_SUBDISPLAY_VERSION_0003 = 3,
|
||||
CELL_SUBDISPLAY_MODE_REMOTEPLAY = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_A8R8G8B8 = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_R8G8B8A8 = 2,
|
||||
CELL_SUBDISPLAY_VIDEO_FORMAT_YUV420 = 3,
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_16_9 = 0,
|
||||
CELL_SUBDISPLAY_VIDEO_ASPECT_RATIO_4_3 = 1,
|
||||
CELL_SUBDISPLAY_VIDEO_MODE_SETDATA = 0,
|
||||
@@ -34,6 +36,7 @@ enum
|
||||
CELL_SUBDISPLAY_AUDIO_MODE_CAPTURE = 1,
|
||||
CELL_SUBDISPLAY_0001_MEMORY_CONTAINER_SIZE = 8 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0002_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_0003_MEMORY_CONTAINER_SIZE = 10 * 1024 * 1024,
|
||||
CELL_SUBDISPLAY_NICKNAME_LEN = 256,
|
||||
CELL_SUBDISPLAY_PSPID_LEN = 16,
|
||||
};
|
||||
@@ -82,4 +85,12 @@ struct CellSubDisplayPeerInfo
|
||||
CellSubDisplayNickname pspNickname;
|
||||
};
|
||||
|
||||
struct CellSubDisplayTouchInfo
|
||||
{
|
||||
u8 status;
|
||||
u8 force;
|
||||
be_t<u16> x;
|
||||
be_t<u16> y;
|
||||
};
|
||||
|
||||
using CellSubDisplayHandler = void(s32 cbMsg, u64 cbParam, vm::ptr<void> userdata);
|
||||
@@ -251,6 +251,7 @@ static const char* get_module_id(u16 id)
|
||||
case 0xf034: return "CELL_SYSMODULE_SAIL_REC";
|
||||
case 0xf035: return "CELL_SYSMODULE_SYSUTIL_NP_TROPHY";
|
||||
case 0xf044: return "CELL_SYSMODULE_SYSUTIL_NP_EULA";
|
||||
case 0xf053: return "CELL_SYSMODULE_ADEC_AT3MULTI";
|
||||
case 0xf054: return "CELL_SYSMODULE_LIBATRAC3MULTI";
|
||||
case 0xffff: return "CELL_SYSMODULE_INVALID";
|
||||
}
|
||||
|
||||
@@ -471,6 +471,12 @@ s32 _ZN4cxml8DocumentD1Ev()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN4cxml8Document5ClearEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -507,6 +513,12 @@ s32 _ZNK4cxml7Element12GetAttributeEPKcPNS_9AttributeE()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZNK4cxml7Element13GetFirstChildEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZNK4cxml7Element14GetNextSiblingEv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -537,6 +549,12 @@ s32 _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN8cxmlutil9GetStringERKN4cxml7ElementEPKcPS5_Pj()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
@@ -567,6 +585,36 @@ s32 _ZN8cxmlutil7GetFileERKN4cxml7ElementEPKcPNS0_4FileE()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory3EndEi()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory5BeginEi()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil11FixedMemory8AllocateEN4cxml14AllocationTypeEPvS3_jPS3_Pj()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil12PacketWriter5WriteEPKvjPv()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _ZN16sysutil_cxmlutil12PacketWriterC1EiiRN4cxml8DocumentE()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutil);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutil_E1EC7B6A(vm::ptr<u32> unk)
|
||||
{
|
||||
cellSysutil.todo("cellSysutil_E1EC7B6A(unk=*0x%x)", unk);
|
||||
@@ -636,6 +684,7 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8DocumentC1Ev);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8DocumentD1Ev);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document5ClearEv);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document13CreateElementEPKciPNS_7ElementE);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document14SetHeaderMagicEPKc);
|
||||
REG_FUNC(cellSysutil, _ZN4cxml8Document16CreateFromBufferEPKvjb);
|
||||
@@ -643,17 +692,25 @@ DECLARE(ppu_module_manager::cellSysutil)("cellSysutil", []()
|
||||
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml4File7GetAddrEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element12GetAttributeEPKcPNS_9AttributeE);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element13GetFirstChildEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml7Element14GetNextSiblingEv);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml9Attribute6GetIntEPi);
|
||||
REG_FUNC(cellSysutil, _ZNK4cxml9Attribute7GetFileEPNS_4FileE);
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil6SetIntERKN4cxml7ElementEPKci);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil6GetIntERKN4cxml7ElementEPKcPi);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil8GetFloatERKN4cxml7ElementEPKcPf);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil9GetStringERKN4cxml7ElementEPKcPS5_Pj);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil9SetStringERKN4cxml7ElementEPKcS5_);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil16CheckElementNameERKN4cxml7ElementEPKc);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil16FindChildElementERKN4cxml7ElementEPKcS5_S5_);
|
||||
REG_FUNC(cellSysutil, _ZN8cxmlutil7GetFileERKN4cxml7ElementEPKcPNS0_4FileE);
|
||||
|
||||
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory3EndEi);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory5BeginEi);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil11FixedMemory8AllocateEN4cxml14AllocationTypeEPvS3_jPS3_Pj);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil12PacketWriter5WriteEPKvjPv);
|
||||
REG_FUNC(cellSysutil, _ZN16sysutil_cxmlutil12PacketWriterC1EiiRN4cxml8DocumentE);
|
||||
|
||||
REG_FNID(cellSysutil, 0xE1EC7B6A, cellSysutil_E1EC7B6A);
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#pragma once
|
||||
#pragma once
|
||||
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
|
||||
@@ -7,166 +7,226 @@
|
||||
|
||||
logs::channel cellSysutilAvc2("cellSysutilAvc2");
|
||||
|
||||
s32 cellSysutilAvc2GetPlayerInfo()
|
||||
template<>
|
||||
void fmt_class_string<CellSysutilAvc2Error>::format(std::string& out, u64 arg)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
format_enum(out, arg, [](auto error)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
STR_CASE(CELL_AVC2_ERROR_UNKNOWN);
|
||||
STR_CASE(CELL_AVC2_ERROR_NOT_SUPPORTED);
|
||||
STR_CASE(CELL_AVC2_ERROR_NOT_INITIALIZED);
|
||||
STR_CASE(CELL_AVC2_ERROR_ALREADY_INITIALIZED);
|
||||
STR_CASE(CELL_AVC2_ERROR_INVALID_ARGUMENT);
|
||||
STR_CASE(CELL_AVC2_ERROR_OUT_OF_MEMORY);
|
||||
STR_CASE(CELL_AVC2_ERROR_ERROR_BAD_ID);
|
||||
STR_CASE(CELL_AVC2_ERROR_INVALID_STATUS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TIMEOUT);
|
||||
STR_CASE(CELL_AVC2_ERROR_NO_SESSION);
|
||||
STR_CASE(CELL_AVC2_ERROR_WINDOW_ALREADY_EXISTS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TOO_MANY_WINDOWS);
|
||||
STR_CASE(CELL_AVC2_ERROR_TOO_MANY_PEER_WINDOWS);
|
||||
STR_CASE(CELL_AVC2_ERROR_WINDOW_NOT_FOUND);
|
||||
}
|
||||
|
||||
return unknown;
|
||||
});
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2JoinChat()
|
||||
error_code cellSysutilAvc2GetPlayerInfo(vm::cptr<SceNpMatching2RoomMemberId> player_id, vm::ptr<CellSysutilAvc2PlayerInfo> player_info)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopStreaming()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ChangeVideoResolution()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ShowScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetVideoMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowAttribute()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopStreaming2()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetVoiceMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartVoiceDetection()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2UnloadAsync()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StopVoiceDetection()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetAttribute()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LoadAsync()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetSpeakerVolumeLevel()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowString()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2EstimateMemoryContainerSize()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetVideoMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetPlayerVoiceMuting()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetStreamingTarget()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Unload()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2DestroyWindow()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowPosition()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetSpeakerVolumeLevel()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2IsCameraAttached(vm::ptr<u8> status)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsCameraAttached()");
|
||||
|
||||
*status = CELL_AVC2_CAMERA_STATUS_DETACHED;
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetPlayerInfo(player_id=*0x%x, player_info=*0x%x)", player_id, player_info);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2MicRead()
|
||||
error_code cellSysutilAvc2JoinChat(vm::cptr<SceNpMatching2RoomId> room_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2JoinChat(room_id=*0x%x)", room_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetPlayerVoiceMuting()
|
||||
error_code cellSysutilAvc2StopStreaming()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopStreaming()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2JoinChatRequest()
|
||||
error_code cellSysutilAvc2ChangeVideoResolution(CellSysutilAvc2VideoResolution resolution)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ChangeVideoResolution(resolution=0x%x)", resolution);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartStreaming()
|
||||
error_code cellSysutilAvc2ShowScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ShowScreen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowAttribute()
|
||||
error_code cellSysutilAvc2GetVideoMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetVideoMuting(muting=*0x%x)", muting);
|
||||
|
||||
*muting = 1;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowShowStatus()
|
||||
error_code cellSysutilAvc2GetWindowAttribute(SceNpMatching2RoomMemberId member_id, vm::ptr<CellSysutilAvc2WindowAttribute> attr)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowAttribute(member_id=0x%x, attr=*0x%x)", member_id, attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> option)
|
||||
error_code cellSysutilAvc2StopStreaming2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopStreaming2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetVoiceMuting(u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetVoiceMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StartVoiceDetection()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartVoiceDetection()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2UnloadAsync()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StopVoiceDetection()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StopVoiceDetection()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetAttribute(vm::ptr<CellSysutilAvc2Attribute> attr)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetAttribute(attr=*0x%x)", attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2LoadAsync(SceNpMatching2ContextId ctx_id, u32 container, vm::ptr<CellSysutilAvc2Callback> callback_func, vm::ptr<void> user_data, vm::cptr<CellSysutilAvc2InitParam> init_param)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LoadAsync(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetSpeakerVolumeLevel(f32 level)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerVolumeLevel(level=0x%x)", level);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowString(SceNpMatching2RoomMemberId member_id, vm::cptr<char> string)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowString(member_id=0x%x, string=%s)", member_id, string);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2EstimateMemoryContainerSize(vm::cptr<CellSysutilAvc2InitParam> initparam, vm::ptr<u32> size)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2EstimateMemoryContainerSize(initparam=*0x%x, size=*0x%x)", initparam, size);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetVideoMuting(u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetVideoMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetPlayerVoiceMuting(SceNpMatching2RoomMemberId member_id, u8 muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetPlayerVoiceMuting(member_id=0x%x, muting=0x%x)", member_id, muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetStreamingTarget()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2Unload()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Unload()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2DestroyWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2DestroyWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowPosition(SceNpMatching2RoomMemberId member_id, f32 x, f32 y, f32 z)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowPosition(member_id=0x%x, x=0x%x, y=0x%x, z=0x%x)", member_id, x, y, z);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetSpeakerVolumeLevel(vm::ptr<f32> level)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetSpeakerVolumeLevel(level=*0x%x)", level);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2IsCameraAttached(vm::ptr<u8> status)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsCameraAttached(status=*0x%x)", status);
|
||||
|
||||
*status = CELL_AVC2_CAMERA_STATUS_DETACHED;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2MicRead(vm::ptr<void> ptr, vm::ptr<u32> pSize)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2MicRead(ptr=*0x%x, pSize=*0x%x)", ptr, pSize);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetPlayerVoiceMuting(SceNpMatching2RoomMemberId member_id, vm::ptr<u8> muting)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetPlayerVoiceMuting(member_id=0x%x, muting=*0x%x)", member_id, muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2JoinChatRequest(vm::cptr<SceNpMatching2RoomId> room_id)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2JoinChatRequest(room_id=*0x%x)", room_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2StartStreaming()
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartStreaming()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2SetWindowAttribute(SceNpMatching2RoomMemberId member_id, vm::cptr<CellSysutilAvc2WindowAttribute> attr)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowAttribute(member_id=0x%x, attr=*0x%x)", member_id, attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2GetWindowShowStatus(SceNpMatching2RoomMemberId member_id, vm::ptr<u8> visible)
|
||||
{
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowShowStatus(member_id=0x%x, visible=*0x%x)", member_id, visible);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> option)
|
||||
{
|
||||
cellSysutilAvc2.warning("cellSysutilAvc2InitParam(version=%d, option=*0x%x)", version, option);
|
||||
|
||||
@@ -213,115 +273,142 @@ s32 cellSysutilAvc2InitParam(u16 version, vm::ptr<CellSysutilAvc2InitParam> opti
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowSize()
|
||||
error_code cellSysutilAvc2GetWindowSize(SceNpMatching2RoomMemberId member_id, vm::ptr<f32> width, vm::ptr<f32> height)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowSize(member_id=0x%x, width=*0x%x, height=*0x%x)", member_id, width, height);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetStreamPriority()
|
||||
error_code cellSysutilAvc2SetStreamPriority(u8 priority)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetStreamPriority(priority=0x%x)", priority);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LeaveChatRequest()
|
||||
error_code cellSysutilAvc2LeaveChatRequest()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LeaveChatRequest()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2IsMicAttached()
|
||||
error_code cellSysutilAvc2IsMicAttached(vm::ptr<u8> status)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2IsMicAttached(status=*0x%x)", status);
|
||||
|
||||
*status = CELL_AVC2_MIC_STATUS_DETACHED;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2CreateWindow()
|
||||
error_code cellSysutilAvc2CreateWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2CreateWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetSpeakerMuting()
|
||||
error_code cellSysutilAvc2GetSpeakerMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetSpeakerMuting(muting=*0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2ShowWindow()
|
||||
error_code cellSysutilAvc2ShowWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2ShowWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetWindowSize()
|
||||
error_code cellSysutilAvc2SetWindowSize(SceNpMatching2RoomMemberId member_id, f32 width, f32 height)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetWindowSize(member_id=0x%x, width=0x%x, height=0x%x)", member_id, width, height);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2EnumPlayers()
|
||||
error_code cellSysutilAvc2EnumPlayers(vm::ptr<s32> players_num, vm::ptr<SceNpMatching2RoomMemberId> players_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2EnumPlayers(players_num=*0x%x, players_id=*0x%x)", players_num, players_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowString()
|
||||
error_code cellSysutilAvc2GetWindowString(SceNpMatching2RoomMemberId member_id, vm::ptr<char> string, vm::ptr<u8> len)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowString(member_id=0x%x, string=*0x%x, len=*0x%x)", member_id, string, len);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2LeaveChat()
|
||||
error_code cellSysutilAvc2LeaveChat()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2LeaveChat()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetSpeakerMuting()
|
||||
error_code cellSysutilAvc2SetSpeakerMuting(u8 muting)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetSpeakerMuting(muting=0x%x)", muting);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Load()
|
||||
error_code cellSysutilAvc2Load(SceNpMatching2ContextId ctx_id, u32 container, vm::ptr<CellSysutilAvc2Callback> callback_func, vm::ptr<void> user_data, vm::cptr<CellSysutilAvc2InitParam> init_param)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Load(ctx_id=0x%x, container=0x%x, callback_func=*0x%x, user_data=*0x%x, init_param=*0x%x)", ctx_id, container, callback_func, user_data, init_param);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2SetAttribute()
|
||||
error_code cellSysutilAvc2SetAttribute(vm::cptr<CellSysutilAvc2Attribute> attr)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2SetAttribute(attr=*0x%x)", attr);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2UnloadAsync2()
|
||||
error_code cellSysutilAvc2UnloadAsync2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2UnloadAsync2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2StartStreaming2()
|
||||
error_code cellSysutilAvc2StartStreaming2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2StartStreaming2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2HideScreen()
|
||||
error_code cellSysutilAvc2HideScreen()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2HideScreen()");
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2HideWindow()
|
||||
error_code cellSysutilAvc2HideWindow(SceNpMatching2RoomMemberId member_id)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2HideWindow(member_id=0x%x)", member_id);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetVoiceMuting()
|
||||
error_code cellSysutilAvc2GetVoiceMuting(vm::ptr<u8> muting)
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellSysutilAvc2);
|
||||
return CELL_OK;
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetVoiceMuting(muting=*0x%x)", muting);
|
||||
|
||||
*muting = 1;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetScreenShowStatus()
|
||||
error_code cellSysutilAvc2GetScreenShowStatus(vm::ptr<u8> visible)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetScreenShowStatus(visible=*0x%x)", visible);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2Unload2()
|
||||
error_code cellSysutilAvc2Unload2(CellSysutilAvc2MediaType mediaType)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2Unload2(mediaType=0x%x)", mediaType);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellSysutilAvc2GetWindowPosition()
|
||||
error_code cellSysutilAvc2GetWindowPosition(SceNpMatching2RoomMemberId member_id, vm::ptr<f32> x, vm::ptr<f32> y, vm::ptr<f32> z)
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
cellSysutilAvc2.todo("cellSysutilAvc2GetWindowPosition(member_id=0x%x, x=*0x%x, y=*0x%x, z=*0x%x)", member_id, x, y, z);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace vm { using namespace ps3; }
|
||||
|
||||
// Error codes
|
||||
enum
|
||||
enum CellSysutilAvc2Error : u32
|
||||
{
|
||||
CELL_AVC2_ERROR_UNKNOWN = 0x8002b701,
|
||||
CELL_AVC2_ERROR_NOT_SUPPORTED = 0x8002b702,
|
||||
@@ -113,6 +113,14 @@ enum
|
||||
CELL_AVC2_CAMERA_STATUS_UNKNOWN = 3,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CELL_AVC2_MIC_STATUS_DETACHED = 0,
|
||||
CELL_AVC2_MIC_STATUS_ATTACHED_OFF = 1,
|
||||
CELL_AVC2_MIC_STATUS_ATTACHED_ON = 2,
|
||||
CELL_AVC2_MIC_STATUS_UNKNOWN = 3,
|
||||
};
|
||||
|
||||
typedef u32 CellSysutilAvc2AttributeId;
|
||||
typedef u32 CellSysutilAvc2WindowAttributeId;
|
||||
|
||||
@@ -143,7 +151,7 @@ struct CellSysutilAvc2VideoInitParam
|
||||
be_t<u16> max_video_windows;
|
||||
be_t<u16> max_video_framerate;
|
||||
be_t<u32> max_video_bitrate;
|
||||
CellSysutilAvc2CoordinatesForm coordinates_form;
|
||||
be_t<CellSysutilAvc2CoordinatesForm> coordinates_form;
|
||||
u8 video_stream_sharing;
|
||||
};
|
||||
|
||||
@@ -166,15 +174,15 @@ struct CellSysutilAvc2InitParam
|
||||
|
||||
struct CellSysutilAvc2RoomMemberList
|
||||
{
|
||||
vm::ptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::bptr<SceNpMatching2RoomMemberId> member_id;
|
||||
u8 member_num;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2MemberIpAndPortList
|
||||
{
|
||||
vm::ptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::ptr<u32> dst_addr; // in_addr
|
||||
vm::ptr<u16> dst_port;
|
||||
vm::bptr<SceNpMatching2RoomMemberId> member_id;
|
||||
vm::bptr<u32> dst_addr; // in_addr
|
||||
vm::bptr<u16> dst_port; // in_port_t
|
||||
be_t<SceNpMatching2RoomMemberId> my_member_id;
|
||||
u8 member_num;
|
||||
};
|
||||
@@ -183,7 +191,7 @@ union CellSysutilAvc2AttributeParam
|
||||
{
|
||||
be_t<u64> int_param;
|
||||
be_t<f32> float_param;
|
||||
vm::ptr<void> ptr_param;
|
||||
vm::bptr<void> ptr_param;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2Attribute
|
||||
@@ -196,7 +204,7 @@ union CellSysutilAvc2WindowAttributeParam
|
||||
{
|
||||
be_t<s32> int_vector[4];
|
||||
be_t<f32> float_vector[4];
|
||||
vm::ptr<void> ptr_vector[4];
|
||||
vm::bptr<void> ptr_vector[4];
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2WindowAttribute
|
||||
@@ -204,3 +212,12 @@ struct CellSysutilAvc2WindowAttribute
|
||||
be_t<CellSysutilAvc2WindowAttributeId> attr_id;
|
||||
CellSysutilAvc2WindowAttributeParam attr_param;
|
||||
};
|
||||
|
||||
struct CellSysutilAvc2PlayerInfo
|
||||
{
|
||||
be_t<SceNpMatching2RoomMemberId> member_id;
|
||||
u8 joined;
|
||||
u8 connected;
|
||||
u8 mic_attached;
|
||||
u8 reserved[11];
|
||||
};
|
||||
|
||||
@@ -43,6 +43,12 @@ s32 cellUsbdRegisterLdd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdRegisterCompositeLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdRegisterExtraLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
@@ -61,6 +67,12 @@ s32 cellUsbdUnregisterLdd()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdUnregisterCompositeLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdUnregisterExtraLdd()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
@@ -151,6 +163,13 @@ s32 cellUsbdFreeMemory()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellUsbdResetDevice()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellUsbd);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
{
|
||||
REG_FUNC(cellUsbd, cellUsbdInit);
|
||||
@@ -161,9 +180,11 @@ DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
REG_FUNC(cellUsbd, cellUsbdGetThreadPriority);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterCompositeLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterExtraLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdRegisterExtraLdd2);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterCompositeLdd);
|
||||
REG_FUNC(cellUsbd, cellUsbdUnregisterExtraLdd);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdOpenPipe);
|
||||
@@ -184,4 +205,6 @@ DECLARE(ppu_module_manager::cellUsbd)("cellUsbd", []()
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdAllocateMemory);
|
||||
REG_FUNC(cellUsbd, cellUsbdFreeMemory);
|
||||
|
||||
REG_FUNC(cellUsbd, cellUsbdResetDevice);
|
||||
});
|
||||
|
||||
@@ -128,26 +128,24 @@ error_code cellVideoOutGetResolution(u32 resolutionId, vm::ptr<CellVideoOutResol
|
||||
|
||||
error_code cellVideoOutConfigure(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> option, u32 waitForEvent)
|
||||
{
|
||||
cellSysutil.warning("cellVideoOutConfigure(videoOut=%d, config=*0x%x, option=*0x%x, waitForEvent=%d)", videoOut, config, option, waitForEvent);
|
||||
cellSysutil.todo("cellVideoOutConfigure(videoOut=%d, config=*0x%x, option=*0x%x, waitForEvent=%d)", videoOut, config, option, waitForEvent);
|
||||
|
||||
switch (videoOut)
|
||||
if (!config)
|
||||
{
|
||||
case CELL_VIDEO_OUT_PRIMARY:
|
||||
if (config->resolutionId != g_video_out_resolution_id.at(g_cfg.video.resolution)
|
||||
|| (config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8R8G8B8 &&
|
||||
config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_X8B8G8R8 &&
|
||||
config->format != CELL_VIDEO_OUT_BUFFER_COLOR_FORMAT_R16G16B16X16_FLOAT)
|
||||
|| (config->aspect != CELL_VIDEO_OUT_ASPECT_AUTO && config->aspect != g_video_out_aspect_id.at(g_cfg.video.aspect_ratio)))
|
||||
{
|
||||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
return CELL_OK;
|
||||
|
||||
case CELL_VIDEO_OUT_SECONDARY:
|
||||
return CELL_OK;
|
||||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
|
||||
if (!config->pitch)
|
||||
{
|
||||
return CELL_VIDEO_OUT_ERROR_PARAMETER_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (config->resolutionId == 0x92 || config->resolutionId == 0xa1)
|
||||
{
|
||||
return CELL_VIDEO_OUT_ERROR_ILLEGAL_CONFIGURATION;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellVideoOutGetConfiguration(u32 videoOut, vm::ptr<CellVideoOutConfiguration> config, vm::ptr<CellVideoOutOption> option)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
@@ -511,9 +511,9 @@ s32 sceNpBasicGetEvent(vm::ptr<s32> event, vm::ptr<SceNpUserInfo> from, vm::ptr<
|
||||
sceNp.warning("sceNpBasicGetEvent(event=*0x%x, from=*0x%x, data=*0x%x, size=*0x%x)", event, from, data, size);
|
||||
|
||||
// TODO: Check for other error and pass other events
|
||||
*event = SCE_NP_BASIC_EVENT_OFFLINE;
|
||||
//*event = SCE_NP_BASIC_EVENT_OFFLINE; // This event only indicates a contact is offline, not the current status of the connection
|
||||
|
||||
return CELL_OK;
|
||||
return SCE_NP_BASIC_ERROR_NO_EVENT;
|
||||
}
|
||||
|
||||
s32 sceNpCommerceCreateCtx()
|
||||
@@ -911,6 +911,10 @@ s32 sceNpManagerRegisterCallback(vm::ptr<SceNpManagerCallback> callback, vm::ptr
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return SCE_NP_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -972,7 +976,7 @@ s32 sceNpManagerGetOnlineId(vm::ptr<SceNpOnlineId> onlineId)
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -994,7 +998,7 @@ s32 sceNpManagerGetNpId(ppu_thread& ppu, vm::ptr<SceNpId> npId)
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -1082,7 +1086,7 @@ s32 sceNpManagerGetAccountRegion(vm::ptr<SceNpCountryCode> countryCode, vm::ptr<
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -1104,7 +1108,7 @@ s32 sceNpManagerGetAccountAge(vm::ptr<s32> age)
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -1126,7 +1130,7 @@ s32 sceNpManagerGetContentRatingFlag(vm::ptr<s32> isRestricted, vm::ptr<s32> age
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -1152,7 +1156,7 @@ s32 sceNpManagerGetChatRestrictionFlag(vm::ptr<s32> isRestricted)
|
||||
return SCE_NP_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN || g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
if (g_psn_connection_status != SCE_NP_MANAGER_STATUS_LOGGING_IN && g_psn_connection_status != SCE_NP_MANAGER_STATUS_ONLINE)
|
||||
{
|
||||
return SCE_NP_ERROR_INVALID_STATE;
|
||||
}
|
||||
@@ -1507,6 +1511,18 @@ s32 sceNpScoreGetRankingByRangeAsync()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpScoreGetFriendsRanking()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpScoreGetFriendsRankingAsync()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpScoreCensorComment()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp);
|
||||
@@ -1717,6 +1733,18 @@ s32 sceNpSignalingGetPeerNetInfoResult()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpUtilCanonicalizeNpIdForPs3()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpUtilCanonicalizeNpIdForPsp()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpUtilCmpNpId(vm::ptr<SceNpId> id1, vm::ptr<SceNpId> id2)
|
||||
{
|
||||
sceNp.warning("sceNpUtilCmpNpId(id1=*0x%x, id2=*0x%x)", id1, id2);
|
||||
@@ -1997,6 +2025,8 @@ DECLARE(ppu_module_manager::sceNp)("sceNp", []()
|
||||
REG_FUNC(sceNp, sceNpScoreGetRankingByNpIdAsync);
|
||||
REG_FUNC(sceNp, sceNpScoreGetRankingByRange);
|
||||
REG_FUNC(sceNp, sceNpScoreGetRankingByRangeAsync);
|
||||
REG_FUNC(sceNp, sceNpScoreGetFriendsRanking);
|
||||
REG_FUNC(sceNp, sceNpScoreGetFriendsRankingAsync);
|
||||
REG_FUNC(sceNp, sceNpScoreCensorComment);
|
||||
REG_FUNC(sceNp, sceNpScoreCensorCommentAsync);
|
||||
REG_FUNC(sceNp, sceNpScoreSanitizeComment);
|
||||
@@ -2032,11 +2062,13 @@ DECLARE(ppu_module_manager::sceNp)("sceNp", []()
|
||||
REG_FUNC(sceNp, sceNpSignalingGetPeerNetInfo);
|
||||
REG_FUNC(sceNp, sceNpSignalingCancelPeerNetInfo);
|
||||
REG_FUNC(sceNp, sceNpSignalingGetPeerNetInfoResult);
|
||||
REG_FUNC(sceNp, sceNpUtilCanonicalizeNpIdForPs3);
|
||||
REG_FUNC(sceNp, sceNpUtilCanonicalizeNpIdForPsp);
|
||||
REG_FUNC(sceNp, sceNpUtilCmpNpId);
|
||||
REG_FUNC(sceNp, sceNpUtilCmpNpIdInOrder);
|
||||
REG_FUNC(sceNp, sceNpUtilCmpOnlineId); // 0x8C760B52
|
||||
REG_FUNC(sceNp, sceNpUtilGetPlatformType); // 0xC611029A
|
||||
REG_FUNC(sceNp, sceNpUtilSetPlatformType); // 0xAFC62605
|
||||
REG_FUNC(sceNp, sceNpUtilCmpOnlineId);
|
||||
REG_FUNC(sceNp, sceNpUtilGetPlatformType);
|
||||
REG_FUNC(sceNp, sceNpUtilSetPlatformType);
|
||||
REG_FUNC(sceNp, _sceNpSysutilClientMalloc);
|
||||
REG_FUNC(sceNp, _sceNpSysutilClientFree);
|
||||
REG_FUNC(sceNp, _Z33_sce_np_sysutil_send_empty_packetiPN16sysutil_cxmlutil11FixedMemoryEPKcS3_);
|
||||
|
||||
@@ -678,7 +678,7 @@ union SceNpSignalingConnectionInfo
|
||||
SceNpId npId;
|
||||
struct address {
|
||||
be_t<u32> addr; // in_addr
|
||||
//in_port_t port; // TODO: Implement this?
|
||||
be_t<u16> port; // in_port_t
|
||||
};
|
||||
be_t<u32> packet_loss;
|
||||
};
|
||||
|
||||
@@ -445,6 +445,65 @@ s32 sceNpMatching2RegisterRoomMessageCallback()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpMatching2SignalingCancelPeerNetInfo()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpMatching2SignalingGetLocalNetInfo()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpMatching2SignalingGetPeerNetInfo()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpMatching2SignalingGetPeerNetInfoResult()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthOAuthInit()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthOAuthTerm()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthCreateOAuthRequest()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthDeleteOAuthRequest()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthAbortOAuthRequest()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpAuthGetAuthorizationCode()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNp2);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
DECLARE(ppu_module_manager::sceNp2)("sceNp2", []()
|
||||
{
|
||||
@@ -517,4 +576,15 @@ DECLARE(ppu_module_manager::sceNp2)("sceNp2", []()
|
||||
REG_FUNC(sceNp2, sceNpMatching2Init2);
|
||||
REG_FUNC(sceNp2, sceNpMatching2SetLobbyMemberDataInternal);
|
||||
REG_FUNC(sceNp2, sceNpMatching2RegisterRoomMessageCallback);
|
||||
REG_FUNC(sceNp2, sceNpMatching2SignalingCancelPeerNetInfo);
|
||||
REG_FUNC(sceNp2, sceNpMatching2SignalingGetLocalNetInfo);
|
||||
REG_FUNC(sceNp2, sceNpMatching2SignalingGetPeerNetInfo);
|
||||
REG_FUNC(sceNp2, sceNpMatching2SignalingGetPeerNetInfoResult);
|
||||
|
||||
REG_FUNC(sceNp2, sceNpAuthOAuthInit);
|
||||
REG_FUNC(sceNp2, sceNpAuthOAuthTerm);
|
||||
REG_FUNC(sceNp2, sceNpAuthCreateOAuthRequest);
|
||||
REG_FUNC(sceNp2, sceNpAuthDeleteOAuthRequest);
|
||||
REG_FUNC(sceNp2, sceNpAuthAbortOAuthRequest);
|
||||
REG_FUNC(sceNp2, sceNpAuthGetAuthorizationCode);
|
||||
});
|
||||
|
||||
@@ -155,6 +155,11 @@ s32 sceNpSnsFbLoadThrottle()
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
s32 sceNpSnsFbGetLongAccessToken()
|
||||
{
|
||||
fmt::throw_exception("Unimplemented" HERE);
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::sceNpSns)("sceNpSns", []()
|
||||
{
|
||||
@@ -164,7 +169,7 @@ DECLARE(ppu_module_manager::sceNpSns)("sceNpSns", []()
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbDestroyHandle);
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbAbortHandle);
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbGetAccessToken);
|
||||
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbGetLongAccessToken);
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbStreamPublish);
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbCheckThrottle);
|
||||
REG_FUNC(sceNpSns, sceNpSnsFbCheckConfig);
|
||||
|
||||
@@ -140,6 +140,18 @@ s32 sceNpTusGetMultiUserVariableVUserAsync()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusGetFriendsVariable()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusGetFriendsVariableAsync()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusAddAndGetVariable()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
@@ -308,6 +320,18 @@ s32 sceNpTusGetMultiUserDataStatusVUserAsync()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusGetFriendsDataStatus()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusGetFriendsDataStatusAsync()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTusDeleteMultiSlotData()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
@@ -332,6 +356,31 @@ s32 sceNpTusDeleteMultiSlotDataVUserAsync()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTssGetData()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTssGetDataAsync()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTssGetDataNoLimit()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sceNpTssGetDataNoLimitAsync()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(sceNpTus);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
||||
DECLARE(ppu_module_manager::sceNpTus)("sceNpTus", []()
|
||||
{
|
||||
REG_FUNC(sceNpTus, sceNpTusInit);
|
||||
@@ -356,6 +405,8 @@ DECLARE(ppu_module_manager::sceNpTus)("sceNpTus", []()
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserVariableVUser);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserVariableAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserVariableVUserAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetFriendsVariable);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetFriendsVariableAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusAddAndGetVariable);
|
||||
REG_FUNC(sceNpTus, sceNpTusAddAndGetVariableVUser);
|
||||
REG_FUNC(sceNpTus, sceNpTusAddAndGetVariableAsync);
|
||||
@@ -384,8 +435,14 @@ DECLARE(ppu_module_manager::sceNpTus)("sceNpTus", []()
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserDataStatusVUser);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserDataStatusAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetMultiUserDataStatusVUserAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetFriendsDataStatus);
|
||||
REG_FUNC(sceNpTus, sceNpTusGetFriendsDataStatusAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusDeleteMultiSlotData);
|
||||
REG_FUNC(sceNpTus, sceNpTusDeleteMultiSlotDataVUser);
|
||||
REG_FUNC(sceNpTus, sceNpTusDeleteMultiSlotDataAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTusDeleteMultiSlotDataVUserAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTssGetData);
|
||||
REG_FUNC(sceNpTus, sceNpTssGetDataAsync);
|
||||
REG_FUNC(sceNpTus, sceNpTssGetDataNoLimit);
|
||||
REG_FUNC(sceNpTus, sceNpTssGetDataNoLimitAsync);
|
||||
});
|
||||
|
||||
@@ -18,11 +18,11 @@ vm::ptr<void> _sys_memset(vm::ptr<void> dst, s32 value, u32 size);
|
||||
struct sys_lwmutex_t;
|
||||
struct sys_lwmutex_attribute_t;
|
||||
|
||||
s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attribute_t> attr);
|
||||
s32 sys_lwmutex_lock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout);
|
||||
s32 sys_lwmutex_trylock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
s32 sys_lwmutex_unlock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
s32 sys_lwmutex_destroy(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
error_code sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attribute_t> attr);
|
||||
error_code sys_lwmutex_lock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout);
|
||||
error_code sys_lwmutex_trylock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
error_code sys_lwmutex_unlock(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
error_code sys_lwmutex_destroy(ppu_thread& CPU, vm::ptr<sys_lwmutex_t> lwmutex);
|
||||
|
||||
struct sys_lwmutex_locker
|
||||
{
|
||||
@@ -45,11 +45,11 @@ struct sys_lwmutex_locker
|
||||
struct sys_lwcond_t;
|
||||
struct sys_lwcond_attribute_t;
|
||||
|
||||
s32 sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwcond_attribute_t> attr);
|
||||
s32 sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond);
|
||||
s32 sys_lwcond_signal(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||
s32 sys_lwcond_signal_all(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||
s32 sys_lwcond_signal_to(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id);
|
||||
s32 sys_lwcond_wait(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout);
|
||||
error_code sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwcond_attribute_t> attr);
|
||||
error_code sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond);
|
||||
error_code sys_lwcond_signal(ppu_thread& CPU, vm::ptr<sys_lwcond_t> lwcond);
|
||||
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);
|
||||
|
||||
void sys_ppu_thread_exit(ppu_thread& CPU, u64 val);
|
||||
|
||||
@@ -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);
|
||||
REG_FNID(sys_libc, "memcpy", sys_libc_memcpy).flags = MFF_FORCED_HLE;
|
||||
});
|
||||
|
||||
@@ -31,7 +31,7 @@ struct ps3_fmt_src
|
||||
|
||||
void skip(std::size_t extra)
|
||||
{
|
||||
++g_count += (u32)extra;
|
||||
g_count += (u32)extra + 1;
|
||||
}
|
||||
|
||||
std::size_t fmt_string(std::string& out, std::size_t extra) const
|
||||
|
||||
@@ -5,17 +5,24 @@
|
||||
|
||||
#include "Emu/Cell/lv2/sys_lwmutex.h"
|
||||
#include "Emu/Cell/lv2/sys_lwcond.h"
|
||||
#include "Emu/Cell/lv2/sys_mutex.h"
|
||||
#include "Emu/Cell/lv2/sys_cond.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
extern logs::channel sysPrxForUser;
|
||||
|
||||
s32 sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwcond_attribute_t> attr)
|
||||
extern bool g_avoid_lwm = false;
|
||||
|
||||
error_code sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwcond_attribute_t> attr)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_create(lwcond=*0x%x, lwmutex=*0x%x, attr=*0x%x)", lwcond, lwmutex, attr);
|
||||
|
||||
vm::var<u32> out_id;
|
||||
vm::var<sys_cond_attribute_t> attrs;
|
||||
attrs->pshared = SYS_SYNC_NOT_PROCESS_SHARED;
|
||||
attrs->name_u64 = attr->name_u64;
|
||||
|
||||
if (s32 res = _sys_lwcond_create(out_id, lwmutex->sleep_queue, lwcond, attr->name_u64, 0))
|
||||
if (auto res = g_avoid_lwm ? sys_cond_create(out_id, lwmutex->sleep_queue, attrs) : _sys_lwcond_create(out_id, lwmutex->sleep_queue, lwcond, attr->name_u64, 0))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -25,11 +32,16 @@ s32 sys_lwcond_create(vm::ptr<sys_lwcond_t> lwcond, vm::ptr<sys_lwmutex_t> lwmut
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond)
|
||||
error_code sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_destroy(lwcond=*0x%x)", lwcond);
|
||||
|
||||
if (s32 res = _sys_lwcond_destroy(lwcond->lwcond_queue))
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_cond_destroy(lwcond->lwcond_queue);
|
||||
}
|
||||
|
||||
if (error_code res = _sys_lwcond_destroy(lwcond->lwcond_queue))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -38,16 +50,20 @@ s32 sys_lwcond_destroy(vm::ptr<sys_lwcond_t> lwcond)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwcond_signal(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
error_code sys_lwcond_signal(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_signal(lwcond=*0x%x)", lwcond);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_cond_signal(ppu, lwcond->lwcond_queue);
|
||||
}
|
||||
|
||||
const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;
|
||||
|
||||
if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY)
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal(lwcond->lwcond_queue, 0, -1, 2);
|
||||
return _sys_lwcond_signal(ppu, lwcond->lwcond_queue, 0, -1, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->vars.owner.load() == ppu.id)
|
||||
@@ -56,18 +72,21 @@ s32 sys_lwcond_signal(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
lwmutex->all_info++;
|
||||
|
||||
// call the syscall
|
||||
if (s32 res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, -1, 1))
|
||||
if (error_code res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, -1, 1))
|
||||
{
|
||||
ppu.test_state();
|
||||
lwmutex->all_info--;
|
||||
|
||||
return res == CELL_EPERM ? CELL_OK : res;
|
||||
if (res != CELL_EPERM)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (s32 res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
if (error_code res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
{
|
||||
// if locking failed
|
||||
|
||||
@@ -84,7 +103,7 @@ s32 sys_lwcond_signal(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
lwmutex->all_info++;
|
||||
|
||||
// call the syscall
|
||||
if (s32 res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, -1, 3))
|
||||
if (error_code res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, -1, 3))
|
||||
{
|
||||
ppu.test_state();
|
||||
lwmutex->all_info--;
|
||||
@@ -92,28 +111,35 @@ s32 sys_lwcond_signal(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
// unlock the lightweight mutex
|
||||
sys_lwmutex_unlock(ppu, lwmutex);
|
||||
|
||||
return res == CELL_ENOENT ? CELL_OK : res;
|
||||
if (res != CELL_ENOENT)
|
||||
{
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwcond_signal_all(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
error_code sys_lwcond_signal_all(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_signal_all(lwcond=*0x%x)", lwcond);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_cond_signal_all(ppu, lwcond->lwcond_queue);
|
||||
}
|
||||
|
||||
const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;
|
||||
|
||||
if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY)
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal_all(lwcond->lwcond_queue, lwmutex->sleep_queue, 2);
|
||||
return _sys_lwcond_signal_all(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->vars.owner.load() == ppu.id)
|
||||
{
|
||||
// if owns the mutex, call the syscall
|
||||
const s32 res = _sys_lwcond_signal_all(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, 1);
|
||||
const error_code res = _sys_lwcond_signal_all(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, 1);
|
||||
|
||||
if (res <= 0)
|
||||
{
|
||||
@@ -127,7 +153,7 @@ s32 sys_lwcond_signal_all(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (s32 res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
if (error_code res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
{
|
||||
// if locking failed
|
||||
|
||||
@@ -141,7 +167,7 @@ s32 sys_lwcond_signal_all(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
}
|
||||
|
||||
// if locking succeeded, call the syscall
|
||||
s32 res = _sys_lwcond_signal_all(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, 1);
|
||||
error_code res = _sys_lwcond_signal_all(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, 1);
|
||||
|
||||
ppu.test_state();
|
||||
|
||||
@@ -158,16 +184,20 @@ s32 sys_lwcond_signal_all(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond)
|
||||
return res;
|
||||
}
|
||||
|
||||
s32 sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id)
|
||||
error_code sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_thread_id)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_signal_to(lwcond=*0x%x, ppu_thread_id=0x%x)", lwcond, ppu_thread_id);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_cond_signal_to(ppu, lwcond->lwcond_queue, ppu_thread_id);
|
||||
}
|
||||
|
||||
const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;
|
||||
|
||||
if ((lwmutex->attribute & SYS_SYNC_ATTR_PROTOCOL_MASK) == SYS_SYNC_RETRY)
|
||||
{
|
||||
// TODO (protocol ignored)
|
||||
//return _sys_lwcond_signal(lwcond->lwcond_queue, 0, ppu_thread_id, 2);
|
||||
return _sys_lwcond_signal(ppu, lwcond->lwcond_queue, 0, ppu_thread_id, 2);
|
||||
}
|
||||
|
||||
if (lwmutex->vars.owner.load() == ppu.id)
|
||||
@@ -176,7 +206,7 @@ s32 sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_
|
||||
lwmutex->all_info++;
|
||||
|
||||
// call the syscall
|
||||
if (s32 res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, ppu_thread_id, 1))
|
||||
if (error_code res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, ppu_thread_id, 1))
|
||||
{
|
||||
ppu.test_state();
|
||||
lwmutex->all_info--;
|
||||
@@ -187,7 +217,7 @@ s32 sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
if (s32 res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
if (error_code res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
{
|
||||
// if locking failed
|
||||
|
||||
@@ -204,7 +234,7 @@ s32 sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_
|
||||
lwmutex->all_info++;
|
||||
|
||||
// call the syscall
|
||||
if (s32 res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, ppu_thread_id, 3))
|
||||
if (error_code res = _sys_lwcond_signal(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, ppu_thread_id, 3))
|
||||
{
|
||||
ppu.test_state();
|
||||
lwmutex->all_info--;
|
||||
@@ -218,10 +248,15 @@ s32 sys_lwcond_signal_to(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u32 ppu_
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
error_code sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwcond_wait(lwcond=*0x%x, timeout=0x%llx)", lwcond, timeout);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_cond_wait(ppu, lwcond->lwcond_queue, timeout);
|
||||
}
|
||||
|
||||
const be_t<u32> tid(ppu.id);
|
||||
|
||||
const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;
|
||||
@@ -240,7 +275,7 @@ s32 sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
lwmutex->recursive_count = 0;
|
||||
|
||||
// call the syscall
|
||||
s32 res = _sys_lwcond_queue_wait(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout);
|
||||
const error_code res = _sys_lwcond_queue_wait(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout);
|
||||
|
||||
if (res == CELL_OK || res == CELL_ESRCH)
|
||||
{
|
||||
@@ -253,7 +288,7 @@ s32 sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
const auto old = lwmutex->vars.owner.exchange(tid);
|
||||
lwmutex->recursive_count = recursive_value;
|
||||
|
||||
if (old != lwmutex_reserved)
|
||||
if (old == lwmutex_free || old == lwmutex_dead)
|
||||
{
|
||||
fmt::throw_exception("Locking failed (lwmutex=*0x%x, owner=0x%x)" HERE, lwmutex, old);
|
||||
}
|
||||
@@ -263,17 +298,20 @@ s32 sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
|
||||
if (res == CELL_EBUSY || res == CELL_ETIMEDOUT)
|
||||
{
|
||||
const s32 res2 = sys_lwmutex_lock(ppu, lwmutex, 0);
|
||||
|
||||
if (res2 == CELL_OK)
|
||||
if (error_code res2 = sys_lwmutex_lock(ppu, lwmutex, 0))
|
||||
{
|
||||
// if successfully locked, restore recursive value
|
||||
lwmutex->recursive_count = recursive_value;
|
||||
|
||||
return res == CELL_EBUSY ? CELL_OK : res;
|
||||
return res2;
|
||||
}
|
||||
|
||||
return res2;
|
||||
// if successfully locked, restore recursive value
|
||||
lwmutex->recursive_count = recursive_value;
|
||||
|
||||
if (res == CELL_EBUSY)
|
||||
{
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (res == CELL_EDEADLK)
|
||||
@@ -282,15 +320,15 @@ s32 sys_lwcond_wait(ppu_thread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
|
||||
const auto old = lwmutex->vars.owner.exchange(tid);
|
||||
lwmutex->recursive_count = recursive_value;
|
||||
|
||||
if (old != lwmutex_reserved)
|
||||
if (old == lwmutex_free || old == lwmutex_dead)
|
||||
{
|
||||
fmt::throw_exception("Locking failed (lwmutex=*0x%x, owner=0x%x)" HERE, lwmutex, old);
|
||||
}
|
||||
|
||||
return CELL_ETIMEDOUT;
|
||||
return not_an_error(CELL_ETIMEDOUT);
|
||||
}
|
||||
|
||||
fmt::throw_exception("Unexpected syscall result (lwcond=*0x%x, result=0x%x)" HERE, lwcond, res);
|
||||
fmt::throw_exception("Unexpected syscall result (lwcond=*0x%x, result=0x%x)" HERE, lwcond, +res);
|
||||
}
|
||||
|
||||
void sysPrxForUser_sys_lwcond_init()
|
||||
|
||||
@@ -5,11 +5,14 @@
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_lwmutex.h"
|
||||
#include "Emu/Cell/lv2/sys_mutex.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
extern logs::channel sysPrxForUser;
|
||||
|
||||
s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attribute_t> attr)
|
||||
extern bool g_avoid_lwm;
|
||||
|
||||
error_code sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attribute_t> attr)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwmutex_create(lwmutex=*0x%x, attr=*0x%x)", lwmutex, attr);
|
||||
|
||||
@@ -32,8 +35,16 @@ s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attri
|
||||
}
|
||||
|
||||
vm::var<u32> out_id;
|
||||
vm::var<sys_mutex_attribute_t> attrs;
|
||||
attrs->protocol = attr->protocol;
|
||||
attrs->recursive = attr->recursive;
|
||||
attrs->pshared = SYS_SYNC_NOT_PROCESS_SHARED;
|
||||
attrs->adaptive = SYS_SYNC_NOT_ADAPTIVE;
|
||||
attrs->ipc_key = 0;
|
||||
attrs->flags = 0;
|
||||
attrs->name_u64 = attr->name_u64;
|
||||
|
||||
if (s32 res = _sys_lwmutex_create(out_id, protocol, lwmutex, 0x80000001, attr->name_u64, 0))
|
||||
if (error_code res = g_avoid_lwm ? sys_mutex_create(out_id, attrs) : _sys_lwmutex_create(out_id, protocol, lwmutex, 0x80000001, attr->name_u64, 0))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
@@ -45,10 +56,15 @@ s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attri
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
error_code sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwmutex_destroy(lwmutex=*0x%x)", lwmutex);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_mutex_destroy(lwmutex->sleep_queue);
|
||||
}
|
||||
|
||||
// check to prevent recursive locking in the next call
|
||||
if (lwmutex->vars.owner.load() == ppu.id)
|
||||
{
|
||||
@@ -56,13 +72,13 @@ s32 sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
}
|
||||
|
||||
// attempt to lock the mutex
|
||||
if (s32 res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
if (error_code res = sys_lwmutex_trylock(ppu, lwmutex))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// call the syscall
|
||||
if (s32 res = _sys_lwmutex_destroy(lwmutex->sleep_queue))
|
||||
if (error_code res = _sys_lwmutex_destroy(lwmutex->sleep_queue))
|
||||
{
|
||||
// unlock the mutex if failed
|
||||
sys_lwmutex_unlock(ppu, lwmutex);
|
||||
@@ -76,10 +92,15 @@ s32 sys_lwmutex_destroy(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_lwmutex_lock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout)
|
||||
error_code sys_lwmutex_lock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeout)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwmutex_lock(lwmutex=*0x%x, timeout=0x%llx)", lwmutex, timeout);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_mutex_lock(ppu, lwmutex->sleep_queue, timeout);
|
||||
}
|
||||
|
||||
const be_t<u32> tid(ppu.id);
|
||||
|
||||
// try to lock lightweight mutex
|
||||
@@ -146,7 +167,7 @@ s32 sys_lwmutex_lock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeou
|
||||
}
|
||||
|
||||
// lock using the syscall
|
||||
const s32 res = _sys_lwmutex_lock(ppu, lwmutex->sleep_queue, timeout);
|
||||
const error_code res = _sys_lwmutex_lock(ppu, lwmutex->sleep_queue, timeout);
|
||||
|
||||
lwmutex->all_info--;
|
||||
|
||||
@@ -172,10 +193,15 @@ s32 sys_lwmutex_lock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex, u64 timeou
|
||||
return res;
|
||||
}
|
||||
|
||||
s32 sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
error_code sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwmutex_trylock(lwmutex=*0x%x)", lwmutex);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_mutex_trylock(ppu, lwmutex->sleep_queue);
|
||||
}
|
||||
|
||||
const be_t<u32> tid(ppu.id);
|
||||
|
||||
// try to lock lightweight mutex
|
||||
@@ -219,7 +245,7 @@ s32 sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
if (old_owner == lwmutex_reserved)
|
||||
{
|
||||
// should be locked by the syscall
|
||||
const s32 res = _sys_lwmutex_trylock(lwmutex->sleep_queue);
|
||||
const error_code res = _sys_lwmutex_trylock(lwmutex->sleep_queue);
|
||||
|
||||
if (res == CELL_OK)
|
||||
{
|
||||
@@ -236,13 +262,18 @@ s32 sys_lwmutex_trylock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
}
|
||||
|
||||
// locked by another thread
|
||||
return CELL_EBUSY;
|
||||
return not_an_error(CELL_EBUSY);
|
||||
}
|
||||
|
||||
s32 sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr<sys_lwmutex_t> lwmutex)
|
||||
{
|
||||
sysPrxForUser.trace("sys_lwmutex_unlock(lwmutex=*0x%x)", lwmutex);
|
||||
|
||||
if (g_avoid_lwm)
|
||||
{
|
||||
return sys_mutex_unlock(ppu, lwmutex->sleep_queue);
|
||||
}
|
||||
|
||||
const be_t<u32> tid(ppu.id);
|
||||
|
||||
// check owner
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Utilities/StrUtil.h"
|
||||
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/IdManager.h"
|
||||
#include "Emu/Cell/PPUModule.h"
|
||||
|
||||
#include "Emu/Cell/lv2/sys_mutex.h"
|
||||
#include "Emu/Cell/lv2/sys_cond.h"
|
||||
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
|
||||
extern logs::channel sysPrxForUser;
|
||||
|
||||
using sys_mempool_t = u32;
|
||||
@@ -15,6 +22,9 @@ struct memory_pool_t
|
||||
static const u32 id_step = 1;
|
||||
static const u32 id_count = 1023;
|
||||
|
||||
u32 mutexid;
|
||||
u32 condid;
|
||||
|
||||
vm::ptr<void> chunk;
|
||||
u64 chunk_size;
|
||||
u64 block_size;
|
||||
@@ -22,13 +32,7 @@ struct memory_pool_t
|
||||
std::vector<vm::ptr<void>> free_blocks;
|
||||
};
|
||||
|
||||
vm::ptr<void> sys_mempool_allocate_block(sys_mempool_t mempool)
|
||||
{
|
||||
sysPrxForUser.todo("sys_mempool_allocate_block(mempool=%d)", mempool);
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
s32 sys_mempool_create(vm::ptr<sys_mempool_t> mempool, vm::ptr<void> chunk, const u64 chunk_size, const u64 block_size, const u64 ralignment)
|
||||
s32 sys_mempool_create(ppu_thread& ppu, vm::ptr<sys_mempool_t> mempool, vm::ptr<void> chunk, const u64 chunk_size, const u64 block_size, const u64 ralignment)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_create(mempool=*0x%x, chunk=*0x%x, chunk_size=%d, block_size=%d, ralignment=%d)", mempool, chunk, chunk_size, block_size, ralignment);
|
||||
|
||||
@@ -72,18 +76,65 @@ s32 sys_mempool_create(vm::ptr<sys_mempool_t> mempool, vm::ptr<void> chunk, cons
|
||||
{
|
||||
memory_pool->free_blocks[i] = vm::ptr<void>::make(chunk.addr() + i * block_size);
|
||||
}
|
||||
|
||||
|
||||
// Create synchronization variables
|
||||
vm::var<u32> mutexid;
|
||||
vm::var<sys_mutex_attribute_t> attr;
|
||||
attr->protocol = SYS_SYNC_PRIORITY;
|
||||
attr->recursive = SYS_SYNC_NOT_RECURSIVE;
|
||||
attr->pshared = SYS_SYNC_NOT_PROCESS_SHARED;
|
||||
attr->adaptive = SYS_SYNC_NOT_ADAPTIVE;
|
||||
attr->ipc_key = 0; // No idea what this is
|
||||
attr->flags = 0; // Also no idea what this is.
|
||||
strcpy_trunc(attr->name, "mp_m" + std::to_string(*mempool));
|
||||
|
||||
error_code ret = sys_mutex_create(mutexid, attr);
|
||||
if (ret != 0)
|
||||
{ // TODO: Better exception handling.
|
||||
fmt::throw_exception("mempool %x failed to create mutex", mempool);
|
||||
}
|
||||
memory_pool->mutexid = *mutexid;
|
||||
|
||||
vm::var<u32> condid;
|
||||
vm::var<sys_cond_attribute_t> condAttr;
|
||||
condAttr->pshared = SYS_SYNC_NOT_PROCESS_SHARED;
|
||||
condAttr->flags = 0; // No idea what this is
|
||||
condAttr->ipc_key = 0; // Also no idea what this is
|
||||
strcpy_trunc(condAttr->name, "mp_c" + std::to_string(*mempool));
|
||||
|
||||
ret = sys_cond_create(condid, *mutexid, condAttr);
|
||||
if (ret != CELL_OK)
|
||||
{ // TODO: Better exception handling.
|
||||
fmt::throw_exception("mempool %x failed to create condition variable", mempool);
|
||||
}
|
||||
memory_pool->condid = *condid;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
void sys_mempool_destroy(sys_mempool_t mempool)
|
||||
void sys_mempool_destroy(ppu_thread& ppu, sys_mempool_t mempool)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_destroy(mempool=%d)", mempool);
|
||||
|
||||
idm::remove<memory_pool_t>(mempool);
|
||||
auto memory_pool = idm::get<memory_pool_t>(mempool);
|
||||
if (memory_pool)
|
||||
{
|
||||
u32 condid = memory_pool->condid;
|
||||
u32 mutexid = memory_pool->mutexid;
|
||||
|
||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||
idm::remove<memory_pool_t>(mempool);
|
||||
sys_mutex_unlock(ppu, mutexid);
|
||||
sys_mutex_destroy(mutexid);
|
||||
sys_cond_destroy(condid);
|
||||
}
|
||||
else
|
||||
{
|
||||
sysPrxForUser.error("Trying to destroy an already destroyed mempool=%d", mempool);
|
||||
}
|
||||
}
|
||||
|
||||
s32 sys_mempool_free_block(sys_mempool_t mempool, vm::ptr<void> block)
|
||||
s32 sys_mempool_free_block(ppu_thread& ppu, sys_mempool_t mempool, vm::ptr<void> block)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_free_block(mempool=%d, block=*0x%x)", mempool, block);
|
||||
|
||||
@@ -93,16 +144,21 @@ s32 sys_mempool_free_block(sys_mempool_t mempool, vm::ptr<void> block)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||
|
||||
// Cannot free a block not belonging to this memory pool
|
||||
if (block.addr() > memory_pool->chunk.addr() + memory_pool->chunk_size)
|
||||
{
|
||||
sys_mutex_unlock(ppu, memory_pool->mutexid);
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
memory_pool->free_blocks.push_back(block);
|
||||
sys_cond_signal(ppu, memory_pool->condid);
|
||||
sys_mutex_unlock(ppu, memory_pool->mutexid);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
u64 sys_mempool_get_count(sys_mempool_t mempool)
|
||||
u64 sys_mempool_get_count(ppu_thread& ppu, sys_mempool_t mempool)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_get_count(mempool=%d)", mempool);
|
||||
|
||||
@@ -111,11 +167,40 @@ u64 sys_mempool_get_count(sys_mempool_t mempool)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
return memory_pool->free_blocks.size();
|
||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||
u64 ret = memory_pool->free_blocks.size();
|
||||
sys_mutex_unlock(ppu, memory_pool->mutexid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
vm::ptr<void> sys_mempool_try_allocate_block(sys_mempool_t mempool)
|
||||
vm::ptr<void> sys_mempool_allocate_block(ppu_thread& ppu, sys_mempool_t mempool)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_allocate_block(mempool=%d)", mempool);
|
||||
|
||||
auto memory_pool = idm::get<memory_pool_t>(mempool);
|
||||
if (!memory_pool)
|
||||
{ // if the memory pool gets deleted-- is null, clearly it's impossible to allocate memory.
|
||||
return vm::null;
|
||||
}
|
||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||
|
||||
while (memory_pool->free_blocks.size() == 0) // while is to guard against spurious wakeups
|
||||
{
|
||||
sys_cond_wait(ppu, memory_pool->condid, 0);
|
||||
memory_pool = idm::get<memory_pool_t>(mempool);
|
||||
if (!memory_pool) // in case spurious wake up was from delete, don't die by accessing a freed pool.
|
||||
{ // No need to unlock as if the pool is freed, the lock was freed as well.
|
||||
return vm::null;
|
||||
}
|
||||
}
|
||||
|
||||
auto block_ptr = memory_pool->free_blocks.back();
|
||||
memory_pool->free_blocks.pop_back();
|
||||
sys_mutex_unlock(ppu, memory_pool->mutexid);
|
||||
return block_ptr;
|
||||
}
|
||||
|
||||
vm::ptr<void> sys_mempool_try_allocate_block(ppu_thread& ppu, sys_mempool_t mempool)
|
||||
{
|
||||
sysPrxForUser.warning("sys_mempool_try_allocate_block(mempool=%d)", mempool);
|
||||
|
||||
@@ -126,12 +211,14 @@ vm::ptr<void> sys_mempool_try_allocate_block(sys_mempool_t mempool)
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
sys_mutex_lock(ppu, memory_pool->mutexid, 0);
|
||||
|
||||
auto block_ptr = memory_pool->free_blocks.back();
|
||||
memory_pool->free_blocks.pop_back();
|
||||
sys_mutex_unlock(ppu, memory_pool->mutexid);
|
||||
return block_ptr;
|
||||
}
|
||||
|
||||
|
||||
void sysPrxForUser_sys_mempool_init()
|
||||
{
|
||||
REG_FUNC(sysPrxForUser, sys_mempool_allocate_block);
|
||||
|
||||
@@ -567,24 +567,43 @@ namespace sys_net
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (level != SOL_SOCKET && level != IPPROTO_TCP)
|
||||
if (level != PS3_SOL_SOCKET && level != IPPROTO_TCP)
|
||||
{
|
||||
fmt::throw_exception("Invalid socket option level!" HERE);
|
||||
}
|
||||
|
||||
s32 ret;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (level == SOL_SOCKET)
|
||||
if (level == PS3_SOL_SOCKET)
|
||||
{
|
||||
switch (optname)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
case OP_SO_NBIO:
|
||||
{
|
||||
unsigned long mode = *(unsigned long*)optval.get_ptr();
|
||||
ret = ioctlsocket(sock->s, FIONBIO, &mode);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case OP_SO_NBIO:
|
||||
{
|
||||
// Obtain the flags
|
||||
s32 flags = fcntl(s, F_GETFL, 0);
|
||||
|
||||
if (flags < 0)
|
||||
{
|
||||
fmt::throw_exception("Failed to obtain socket flags." HERE);
|
||||
}
|
||||
|
||||
u32 mode = *(u32*)optval.get_ptr();
|
||||
flags = mode ? (flags &~O_NONBLOCK) : (flags | O_NONBLOCK);
|
||||
|
||||
// Re-set the flags
|
||||
ret = fcntl(sock->s, F_SETFL, flags);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case OP_SO_SNDBUF:
|
||||
{
|
||||
u32 sendbuff = *(u32*)optval.get_ptr();
|
||||
@@ -623,12 +642,14 @@ namespace sys_net
|
||||
}
|
||||
case OP_SO_USECRYPTO:
|
||||
{
|
||||
libnet.warning("Socket option OP_SO_USECRYPTO is unimplemented");
|
||||
libnet.todo("Socket option OP_SO_USECRYPTO is unimplemented");
|
||||
ret = CELL_OK;
|
||||
break;
|
||||
}
|
||||
case OP_SO_USESIGNATURE:
|
||||
{
|
||||
libnet.warning("Socket option OP_SO_USESIGNATURE is unimplemented");
|
||||
libnet.todo("Socket option OP_SO_USESIGNATURE is unimplemented");
|
||||
ret = CELL_OK;
|
||||
break;
|
||||
}
|
||||
case OP_SO_BROADCAST:
|
||||
@@ -644,7 +665,7 @@ namespace sys_net
|
||||
break;
|
||||
}
|
||||
default:
|
||||
libnet.error("Unknown socket option for Win32: 0x%x", optname);
|
||||
libnet.error("Unknown socket option: 0x%x", optname);
|
||||
}
|
||||
}
|
||||
else if (level == PROTO_IPPROTO_TCP)
|
||||
@@ -653,71 +674,31 @@ namespace sys_net
|
||||
{
|
||||
case OP_TCP_NODELAY:
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const char delay = *(char*)optval.get_ptr();
|
||||
ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_NODELAY, &delay, sizeof(delay));
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_TCP_MAXSEG:
|
||||
{
|
||||
libnet.warning("TCP_MAXSEG can't be set on Windows.");
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
libnet.error("Unknown TCP option for Win32: 0x%x", optname);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (level == SOL_SOCKET)
|
||||
{
|
||||
switch (optname)
|
||||
{
|
||||
case OP_SO_NBIO:
|
||||
{
|
||||
// Obtain the flags
|
||||
s32 flags = fcntl(s, F_GETFL, 0);
|
||||
|
||||
if (flags < 0)
|
||||
{
|
||||
fmt::throw_exception("Failed to obtain socket flags." HERE);
|
||||
}
|
||||
|
||||
u32 mode = *(u32*)optval.get_ptr();
|
||||
flags = mode ? (flags &~O_NONBLOCK) : (flags | O_NONBLOCK);
|
||||
|
||||
// Re-set the flags
|
||||
ret = fcntl(sock->s, F_SETFL, flags);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
libnet.error("Unknown socket option for Unix: 0x%x", optname);
|
||||
}
|
||||
}
|
||||
else if (level == PROTO_IPPROTO_TCP)
|
||||
{
|
||||
switch (optname)
|
||||
{
|
||||
case OP_TCP_NODELAY:
|
||||
{
|
||||
u32 delay = *(u32*)optval.get_ptr();
|
||||
ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_NODELAY, &delay, optlen);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_TCP_MAXSEG:
|
||||
{
|
||||
#ifdef _WIN32
|
||||
libnet.warning("TCP_MAXSEG can't be set on Windows.");
|
||||
#else
|
||||
u32 maxseg = *(u32*)optval.get_ptr();
|
||||
ret = ::setsockopt(sock->s, IPPROTO_TCP, TCP_MAXSEG, &maxseg, optlen);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
libnet.error("Unknown TCP option for Unix: 0x%x", optname);
|
||||
libnet.error("Unknown TCP option: 0x%x", optname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
@@ -821,8 +802,8 @@ namespace sys_net
|
||||
|
||||
s32 socketselect(s32 nfds, vm::ptr<fd_set> readfds, vm::ptr<fd_set> writefds, vm::ptr<fd_set> exceptfds, vm::ptr<timeval> timeout)
|
||||
{
|
||||
libnet.warning("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout=*0x%x)", nfds, readfds, writefds, exceptfds, timeout);
|
||||
|
||||
libnet.warning("socketselect(nfds=%d, readfds=*0x%x, writefds=*0x%x, exceptfds=*0x%x, timeout.tv_sec=%d, timeout.tv_usec=%d)",
|
||||
nfds, readfds, writefds, exceptfds, timeout->tv_sec, timeout->tv_usec);
|
||||
::timeval _timeout;
|
||||
|
||||
if (timeout)
|
||||
@@ -830,8 +811,12 @@ namespace sys_net
|
||||
_timeout.tv_sec = timeout->tv_sec;
|
||||
_timeout.tv_usec = timeout->tv_usec;
|
||||
}
|
||||
|
||||
//libnet.error("timeval: %d . %d", _timeout.tv_sec, _timeout.tv_usec);
|
||||
|
||||
if (_timeout.tv_usec >= 1000000)
|
||||
{
|
||||
_timeout.tv_sec = _timeout.tv_sec ? _timeout.tv_sec - 1 : _timeout.tv_sec + 1;
|
||||
_timeout.tv_usec = 0;
|
||||
}
|
||||
|
||||
::fd_set _readfds;
|
||||
::fd_set _writefds;
|
||||
@@ -1226,6 +1211,12 @@ namespace sys_net
|
||||
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);
|
||||
@@ -1357,6 +1348,7 @@ DECLARE(ppu_module_manager::libnet)("sys_net", []()
|
||||
REG_FUNC_(sys_netset_if_up);
|
||||
REG_FUNC_(sys_netset_open);
|
||||
|
||||
REG_FUNC_(_sce_net_add_name_server);
|
||||
REG_FUNC_(_sce_net_add_name_server_with_char);
|
||||
REG_FUNC_(_sce_net_flush_route);
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@ 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
|
||||
{
|
||||
|
||||
@@ -229,7 +229,7 @@ error_code sys_prx_get_module_info(ppu_thread& ppu, u32 id, u64 flags, vm::ptr<s
|
||||
return _sys_prx_get_module_info(id, 0, opt);
|
||||
}
|
||||
|
||||
error_code sys_prx_get_module_id_by_name(vm::cptr<char> name, u64 flags, vm::ps3::ptr<sys_prx_get_module_id_by_name_option_t> pOpt)
|
||||
error_code sys_prx_get_module_id_by_name(vm::cptr<char> name, u64 flags, vm::ptr<sys_prx_get_module_id_by_name_option_t> pOpt)
|
||||
{
|
||||
sysPrxForUser.trace("sys_prx_get_module_id_by_name(name=%s, flags=0x%x, pOpt=*0x%x)", name, flags, pOpt);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Emu/Cell/RawSPUThread.h"
|
||||
#include "Emu/Cell/lv2/sys_spu.h"
|
||||
#include "Crypto/unself.h"
|
||||
#include "Loader/ELF.h"
|
||||
#include "sysPrxForUser.h"
|
||||
|
||||
extern logs::channel sysPrxForUser;
|
||||
@@ -16,46 +17,365 @@ spu_printf_cb_t g_spu_printf_dgcb;
|
||||
spu_printf_cb_t g_spu_printf_atcb;
|
||||
spu_printf_cb_t g_spu_printf_dtcb;
|
||||
|
||||
s32 sys_spu_elf_get_information(u32 elf_img, vm::ptr<u32> entry, vm::ptr<s32> nseg)
|
||||
struct spu_elf_ldr
|
||||
{
|
||||
sysPrxForUser.todo("sys_spu_elf_get_information(elf_img=0x%x, entry=*0x%x, nseg=*0x%x)", elf_img, entry, nseg);
|
||||
be_t<u32> _vtable;
|
||||
vm::bptr<void> src;
|
||||
be_t<u32> x8;
|
||||
be_t<u64> ehdr_off;
|
||||
be_t<u64> phdr_off;
|
||||
|
||||
s32 get_ehdr(vm::ptr<elf_ehdr<elf_be, u64>> out)
|
||||
{
|
||||
if (!src)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_vtable == vm::cast(u32{1}))
|
||||
{
|
||||
vm::ptr<elf_ehdr<elf_be, u32>> ehdr = vm::cast(src.addr() + ehdr_off);
|
||||
std::memcpy(out.get_ptr(), ehdr.get_ptr(), 0x10); // Not needed?
|
||||
out->e_type = ehdr->e_type;
|
||||
out->e_machine = ehdr->e_machine;
|
||||
out->e_version = ehdr->e_version;
|
||||
out->e_entry = ehdr->e_entry;
|
||||
out->e_phoff = ehdr->e_phoff;
|
||||
out->e_shoff = ehdr->e_shoff;
|
||||
out->e_flags = ehdr->e_flags;
|
||||
out->e_ehsize = ehdr->e_ehsize;
|
||||
out->e_phentsize = ehdr->e_phentsize;
|
||||
out->e_phnum = ehdr->e_phnum;
|
||||
out->e_shentsize = ehdr->e_shentsize;
|
||||
out->e_shnum = ehdr->e_shnum;
|
||||
out->e_shstrndx = ehdr->e_shstrndx;
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::ptr<elf_ehdr<elf_be, u64>> ehdr = vm::cast(src.addr() + ehdr_off);
|
||||
*out = *ehdr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
s32 get_phdr(vm::ptr<elf_phdr<elf_be, u64>> out, u32 count)
|
||||
{
|
||||
if (!src)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_vtable == vm::cast(u32{1}))
|
||||
{
|
||||
vm::ptr<elf_ehdr<elf_be, u32>> ehdr = vm::cast(src.addr() + ehdr_off);
|
||||
vm::ptr<elf_phdr<elf_be, u32>> phdr = vm::cast(src.addr() + (phdr_off ? +phdr_off : +ehdr->e_phoff));
|
||||
|
||||
for (; count; count--, phdr++, out++)
|
||||
{
|
||||
out->p_type = phdr->p_type;
|
||||
out->p_flags = phdr->p_flags;
|
||||
out->p_offset = phdr->p_offset;
|
||||
out->p_vaddr = phdr->p_vaddr;
|
||||
out->p_paddr = phdr->p_paddr;
|
||||
out->p_filesz = phdr->p_filesz;
|
||||
out->p_memsz = phdr->p_memsz;
|
||||
out->p_align = phdr->p_align;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vm::ptr<elf_ehdr<elf_be, u64>> ehdr = vm::cast(src.addr() + ehdr_off);
|
||||
vm::ptr<elf_phdr<elf_be, u64>> phdr = vm::cast(src.addr() + (phdr_off ? +phdr_off : +ehdr->e_phoff));
|
||||
|
||||
std::memcpy(out.get_ptr(), phdr.get_ptr(), sizeof(*out) * count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct spu_elf_info
|
||||
{
|
||||
u8 e_class;
|
||||
vm::bptr<spu_elf_ldr> ldr;
|
||||
|
||||
struct sce_hdr
|
||||
{
|
||||
be_t<u32> se_magic;
|
||||
be_t<u32> se_hver;
|
||||
be_t<u16> se_flags;
|
||||
be_t<u16> se_type;
|
||||
be_t<u32> se_meta;
|
||||
be_t<u64> se_hsize;
|
||||
be_t<u64> se_esize;
|
||||
} sce0;
|
||||
|
||||
struct self_hdr
|
||||
{
|
||||
be_t<u64> se_htype;
|
||||
be_t<u64> se_appinfooff;
|
||||
be_t<u64> se_elfoff;
|
||||
be_t<u64> se_phdroff;
|
||||
be_t<u64> se_shdroff;
|
||||
be_t<u64> se_secinfoff;
|
||||
be_t<u64> se_sceveroff;
|
||||
be_t<u64> se_controloff;
|
||||
be_t<u64> se_controlsize;
|
||||
be_t<u64> pad;
|
||||
} self;
|
||||
|
||||
// Doesn't exist there
|
||||
spu_elf_ldr _overlay;
|
||||
|
||||
error_code init(vm::ptr<void> src, s32 arg2 = 0)
|
||||
{
|
||||
if (!src)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
u32 ehdr_off = 0;
|
||||
u32 phdr_off = 0;
|
||||
|
||||
// Check SCE header if found
|
||||
std::memcpy(&sce0, src.get_ptr(), sizeof(sce0));
|
||||
|
||||
if (sce0.se_magic == 0x53434500 /* SCE\0 */)
|
||||
{
|
||||
if (sce0.se_hver != 2 || sce0.se_type != 1 || sce0.se_meta == 0)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
std::memcpy(&self, src.get_ptr(), sizeof(self));
|
||||
ehdr_off = static_cast<u32>(+self.se_elfoff);
|
||||
phdr_off = static_cast<u32>(+self.se_phdroff);
|
||||
|
||||
if (self.se_htype != 3 || !ehdr_off || !phdr_off)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
}
|
||||
|
||||
// Check ELF header
|
||||
vm::ptr<elf_ehdr<elf_be, u32>> ehdr = vm::cast(src.addr() + ehdr_off);
|
||||
|
||||
if (ehdr->e_magic != "\177ELF"_u32 || ehdr->e_data != 2 /* BE */)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
if (ehdr->e_class != 1 && ehdr->e_class != 2)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
e_class = ehdr->e_class;
|
||||
ldr = vm::get_addr(&_overlay);
|
||||
ldr->_vtable = vm::cast(u32{e_class}); // TODO
|
||||
ldr->src = vm::static_ptr_cast<u8>(src);
|
||||
ldr->x8 = arg2;
|
||||
ldr->ehdr_off = ehdr_off;
|
||||
ldr->phdr_off = phdr_off;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
};
|
||||
|
||||
error_code sys_spu_elf_get_information(u32 elf_img, vm::ptr<u32> entry, vm::ptr<s32> nseg)
|
||||
{
|
||||
sysPrxForUser.warning("sys_spu_elf_get_information(elf_img=0x%x, entry=*0x%x, nseg=*0x%x)", elf_img, entry, nseg);
|
||||
|
||||
// Initialize ELF loader
|
||||
vm::var<spu_elf_info> info(spu_elf_info{});
|
||||
|
||||
if (auto res = info->init(vm::cast(elf_img)))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Reject SCE header
|
||||
if (info->sce0.se_magic == 0x53434500)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
// Load ELF header
|
||||
vm::var<elf_ehdr<elf_be, u64>> ehdr(elf_ehdr<elf_be, u64>{});
|
||||
|
||||
if (info->ldr->get_ehdr(ehdr) || ehdr->e_machine != elf_machine::spu || !ehdr->e_phnum)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
// Load program headers
|
||||
vm::var<elf_phdr<elf_be, u64>[]> phdr(ehdr->e_phnum);
|
||||
|
||||
if (info->ldr->get_phdr(phdr, ehdr->e_phnum))
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
const s32 num_segs = sys_spu_image::get_nsegs<false>(phdr);
|
||||
|
||||
if (num_segs < 0)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
*entry = static_cast<u32>(ehdr->e_entry);
|
||||
*nseg = num_segs;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_spu_elf_get_segments(u32 elf_img, vm::ptr<sys_spu_segment> segments, s32 nseg)
|
||||
error_code sys_spu_elf_get_segments(u32 elf_img, vm::ptr<sys_spu_segment> segments, s32 nseg)
|
||||
{
|
||||
sysPrxForUser.todo("sys_spu_elf_get_segments(elf_img=0x%x, segments=*0x%x, nseg=0x%x)", elf_img, segments, nseg);
|
||||
sysPrxForUser.warning("sys_spu_elf_get_segments(elf_img=0x%x, segments=*0x%x, nseg=0x%x)", elf_img, segments, nseg);
|
||||
|
||||
// Initialize ELF loader
|
||||
vm::var<spu_elf_info> info(spu_elf_info{});
|
||||
|
||||
if (auto res = info->init(vm::cast(elf_img)))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Load ELF header
|
||||
vm::var<elf_ehdr<elf_be, u64>> ehdr(elf_ehdr<elf_be, u64>{});
|
||||
|
||||
if (info->ldr->get_ehdr(ehdr) || ehdr->e_machine != elf_machine::spu || !ehdr->e_phnum)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
// Load program headers
|
||||
vm::var<elf_phdr<elf_be, u64>[]> phdr(ehdr->e_phnum);
|
||||
|
||||
if (info->ldr->get_phdr(phdr, ehdr->e_phnum))
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
const s32 num_segs = sys_spu_image::fill<false>(segments, nseg, phdr, elf_img);
|
||||
|
||||
if (num_segs == -2)
|
||||
{
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
else if (num_segs < 0)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 sys_spu_image_import(vm::ptr<sys_spu_image> img, u32 src, u32 type)
|
||||
error_code sys_spu_image_import(vm::ptr<sys_spu_image> img, u32 src, u32 type)
|
||||
{
|
||||
sysPrxForUser.warning("sys_spu_image_import(img=*0x%x, src=0x%x, type=%d)", img, src, type);
|
||||
|
||||
// Load from memory (TODO)
|
||||
img->load(fs::file{vm::base(src), 0 - src});
|
||||
if (type != SYS_SPU_IMAGE_PROTECT && type != SYS_SPU_IMAGE_DIRECT)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
// Initialize ELF loader
|
||||
vm::var<spu_elf_info> info(spu_elf_info{});
|
||||
|
||||
if (auto res = info->init(vm::cast(src)))
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
// Reject SCE header
|
||||
if (info->sce0.se_magic == 0x53434500)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
// Load ELF header
|
||||
vm::var<elf_ehdr<elf_be, u64>> ehdr(elf_ehdr<elf_be, u64>{});
|
||||
|
||||
if (info->ldr->get_ehdr(ehdr) || ehdr->e_machine != elf_machine::spu || !ehdr->e_phnum)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
// Load program headers
|
||||
vm::var<elf_phdr<elf_be, u64>[]> phdr(ehdr->e_phnum);
|
||||
|
||||
if (info->ldr->get_phdr(phdr, ehdr->e_phnum))
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
if (type == SYS_SPU_IMAGE_PROTECT)
|
||||
{
|
||||
u32 img_size = 0;
|
||||
|
||||
for (const auto& p : phdr)
|
||||
{
|
||||
if (p.p_type != 1 && p.p_type != 4)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
img_size = std::max<u32>(img_size, static_cast<u32>(p.p_offset + p.p_filesz));
|
||||
}
|
||||
|
||||
return _sys_spu_image_import(img, src, img_size, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
s32 num_segs = sys_spu_image::get_nsegs(phdr);
|
||||
|
||||
if (num_segs < 0)
|
||||
{
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
img->nsegs = num_segs;
|
||||
img->entry_point = static_cast<u32>(ehdr->e_entry);
|
||||
|
||||
vm::ptr<sys_spu_segment> segs = vm::cast(vm::alloc(num_segs * sizeof(sys_spu_segment), vm::main));
|
||||
|
||||
if (!segs)
|
||||
{
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
if (sys_spu_image::fill(segs, num_segs, phdr, src) != num_segs)
|
||||
{
|
||||
vm::dealloc(segs.addr());
|
||||
return CELL_ENOEXEC;
|
||||
}
|
||||
|
||||
img->type = SYS_SPU_IMAGE_TYPE_USER;
|
||||
img->segs = segs;
|
||||
return CELL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
s32 sys_spu_image_close(vm::ptr<sys_spu_image> img)
|
||||
error_code sys_spu_image_close(vm::ptr<sys_spu_image> img)
|
||||
{
|
||||
sysPrxForUser.warning("sys_spu_image_close(img=*0x%x)", img);
|
||||
|
||||
if (img->type == SYS_SPU_IMAGE_TYPE_USER)
|
||||
{
|
||||
//_sys_free(img->segs.addr());
|
||||
vm::dealloc_verbose_nothrow(img->segs.addr(), vm::main);
|
||||
}
|
||||
else if (img->type == SYS_SPU_IMAGE_TYPE_KERNEL)
|
||||
{
|
||||
//return syscall_158(img);
|
||||
// Call the syscall
|
||||
return _sys_spu_image_close(img);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
img->free();
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@@ -63,7 +383,7 @@ s32 sys_raw_spu_load(s32 id, vm::cptr<char> path, vm::ptr<u32> entry)
|
||||
{
|
||||
sysPrxForUser.warning("sys_raw_spu_load(id=%d, path=%s, entry=*0x%x)", id, path, entry);
|
||||
|
||||
const fs::file elf_file = decrypt_self(fs::file(vfs::get(path.get_ptr())));
|
||||
const fs::file elf_file = fs::file(vfs::get(path.get_ptr()));
|
||||
|
||||
if (!elf_file)
|
||||
{
|
||||
@@ -73,10 +393,10 @@ s32 sys_raw_spu_load(s32 id, vm::cptr<char> path, vm::ptr<u32> entry)
|
||||
|
||||
sys_spu_image img;
|
||||
img.load(elf_file);
|
||||
img.deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id);
|
||||
img.deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, img.segs.get_ptr(), img.nsegs);
|
||||
img.free();
|
||||
|
||||
*entry = img.entry_point | 1;
|
||||
*entry = img.entry_point;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
@@ -86,15 +406,15 @@ s32 sys_raw_spu_image_load(ppu_thread& ppu, s32 id, vm::ptr<sys_spu_image> img)
|
||||
sysPrxForUser.warning("sys_raw_spu_image_load(id=%d, img=*0x%x)", id, img);
|
||||
|
||||
// Load SPU segments
|
||||
img->deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id);
|
||||
img->deploy(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id, img->segs.get_ptr(), img->nsegs);
|
||||
|
||||
// Use MMIO
|
||||
vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point | 1);
|
||||
vm::write32(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * id + RAW_SPU_PROB_OFFSET + SPU_NPC_offs, img->entry_point);
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_initialize(spu_printf_cb_t agcb, spu_printf_cb_t dgcb, spu_printf_cb_t atcb, spu_printf_cb_t dtcb)
|
||||
error_code _sys_spu_printf_initialize(spu_printf_cb_t agcb, spu_printf_cb_t dgcb, spu_printf_cb_t atcb, spu_printf_cb_t dtcb)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_initialize(agcb=*0x%x, dgcb=*0x%x, atcb=*0x%x, dtcb=*0x%x)", agcb, dgcb, atcb, dtcb);
|
||||
|
||||
@@ -107,7 +427,7 @@ s32 _sys_spu_printf_initialize(spu_printf_cb_t agcb, spu_printf_cb_t dgcb, spu_p
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_finalize()
|
||||
error_code _sys_spu_printf_finalize()
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_finalize()");
|
||||
|
||||
@@ -119,7 +439,7 @@ s32 _sys_spu_printf_finalize()
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_attach_group(ppu_thread& ppu, u32 group)
|
||||
error_code _sys_spu_printf_attach_group(ppu_thread& ppu, u32 group)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_attach_group(group=0x%x)", group);
|
||||
|
||||
@@ -131,7 +451,7 @@ s32 _sys_spu_printf_attach_group(ppu_thread& ppu, u32 group)
|
||||
return g_spu_printf_agcb(ppu, group);
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_detach_group(ppu_thread& ppu, u32 group)
|
||||
error_code _sys_spu_printf_detach_group(ppu_thread& ppu, u32 group)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_detach_group(group=0x%x)", group);
|
||||
|
||||
@@ -143,7 +463,7 @@ s32 _sys_spu_printf_detach_group(ppu_thread& ppu, u32 group)
|
||||
return g_spu_printf_dgcb(ppu, group);
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_attach_thread(ppu_thread& ppu, u32 thread)
|
||||
error_code _sys_spu_printf_attach_thread(ppu_thread& ppu, u32 thread)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_attach_thread(thread=0x%x)", thread);
|
||||
|
||||
@@ -155,7 +475,7 @@ s32 _sys_spu_printf_attach_thread(ppu_thread& ppu, u32 thread)
|
||||
return g_spu_printf_atcb(ppu, thread);
|
||||
}
|
||||
|
||||
s32 _sys_spu_printf_detach_thread(ppu_thread& ppu, u32 thread)
|
||||
error_code _sys_spu_printf_detach_thread(ppu_thread& ppu, u32 thread)
|
||||
{
|
||||
sysPrxForUser.warning("_sys_spu_printf_detach_thread(thread=0x%x)", thread);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user