Compare commits
193 Commits
less-shade
...
main
Author | SHA1 | Date |
---|---|---|
psucien | 4182740384 | |
psucien | ca1613258f | |
georgemoralis | 3d375a28eb | |
jnack | 69d4fecdfe | |
Xphalnos | 7886761476 | |
squidbus | 6080066f75 | |
georgemoralis | f1fe6b9f96 | |
squidbus | 6e552aac6a | |
adjonesey | 0f87d1e3d4 | |
georgemoralis | 68fa5e292f | |
bigol83 | bdfff5e8ea | |
georgemoralis | cdd193d5b1 | |
georgemoralis | 30ab2b7f71 | |
DanielSvoboda | f2b6843f9d | |
squidbus | a17150960f | |
Grégoire Hage | 1651db24fe | |
IndecisiveTurtle | 6bf42aa985 | |
georgemoralis | 8d41695e74 | |
IndecisiveTurtle | cb5190e31a | |
IndecisiveTurtle | cf706f8cc7 | |
IndecisiveTurtle | 6fbbe3d79b | |
IndecisiveTurtle | fab390b860 | |
Plínio Larrubia | 5a96ac1a4f | |
georgemoralis | ac2fa103fa | |
georgemoralis | 7e7854346d | |
DanielSvoboda | 751f6f9bab | |
Flamy | 1c835a1aa4 | |
georgemoralis | 07c8c28000 | |
TheTurtle | 66e96dd944 | |
DanielSvoboda | aef7498c49 | |
georgemoralis | 790d19e59b | |
georgemoralis | 3ae18c9073 | |
georgemoralis | 83e343f77e | |
kiwipuppeh | 81eb3a4d14 | |
Marcin Mitura | 37786e06c2 | |
psucien | 9d349a1308 | |
bigol83 | c997490645 | |
bigol83 | 600c5079ce | |
Dzmitry Dubrova | 8827c72a1c | |
¥IGA | e1382b43c8 | |
DanielSvoboda | 614a23b369 | |
georgemoralis | a6a9fff666 | |
psucien | 3fbb68048e | |
CyntexMore | 55be97bca3 | |
georgemoralis | d2e4a200fb | |
georgemoralis | a291800418 | |
bigol83 | 365e17f64e | |
Emulator-Team-2 | af18728962 | |
Emulator-Team-2 | 6f938a10ce | |
Emulator-Team-2 | 08036d2b49 | |
georgemoralis | e57d55e6e9 | |
georgemoralis | 163019e3dc | |
counter185 | bc661039c5 | |
counter185 | 2e2f3bb2c6 | |
counter185 | 89bdd3bba2 | |
counter185 | 15fc267f0d | |
counter185 | 0b24ac6991 | |
counter185 | 698dade864 | |
counter185 | 4e6e90dfb9 | |
georgemoralis | be49871c68 | |
squidbus | 905d49fd96 | |
georgemoralis | dcc4762c7e | |
squidbus | 4a6ce1e0d6 | |
georgemoralis | 878fac7f94 | |
squidbus | da966bedfd | |
Vinicius Rangel | 8192eaa668 | |
0xsegf4ult | 9f4e55a8e7 | |
InvoxiPlayGames | 9d59ea06c7 | |
tGecko | 990da7edcc | |
InvoxiPlayGames | 550cf0188d | |
InvoxiPlayGames | 79e86a39fc | |
Anton Kovalev | dfb30ea955 | |
Random | c37679154e | |
Anton Kovalev | 87ccfdfbbd | |
Exhigh | ed42db47af | |
Anton Kovalev | 1a02efbd15 | |
georgemoralis | e4254ebdaa | |
georgemoralis | e65bf19118 | |
Semenov Herman | 860b935054 | |
Anton Kovalev | 3842993a43 | |
Anton Kovalev | 3d46a5d492 | |
Anton Kovalev | 595b845df0 | |
Anton Kovalev | 659e7a4675 | |
psucien | 3eb47226d9 | |
psucien | 371d1d009a | |
Lizardy | 59b651be07 | |
Grégoire Hage | 288db9a0cf | |
georgemoralis | 62f165a7e4 | |
Vladislav Mikhalin | 2d354a095a | |
SolidStateDj | 7ecc1d3be0 | |
psucien | af4356bfe1 | |
psucien | 3e94b533b6 | |
georgemoralis | 287c3a4ab1 | |
Exhigh | 7c7d04133e | |
Plínio Larrubia | ad8373095a | |
Lizardy | aae6e5be73 | |
Batu | cd6b5abccf | |
Plínio Larrubia | 6520f3ca17 | |
Cristóbal Martí Méndez | d3b6b17c75 | |
Marcin Mitura | 0b5616c493 | |
georgemoralis | 3627393707 | |
nishinji | 6e340bcdc1 | |
psucien | 78e24852f8 | |
georgemoralis | 7f6d08a3c8 | |
nishinji | 7aa8cf992f | |
¥IGA | e16aa2a012 | |
greggameplayer | 86870e7c8d | |
Daniel R. | fae0c0ae85 | |
Yury | 5d7407dc7d | |
bigol83 | bcc3a10557 | |
psucien | 6fd4264b5d | |
DanielSvoboda | 2a737d0800 | |
psucien | b687ae5e34 | |
georgemoralis | c2ddfe51e1 | |
georgemoralis | abc7f55c06 | |
Dzmitry Dubrova | 26b5661dea | |
SaynedBread | 6a87c37aeb | |
SaynedBread | 5664d45305 | |
Dzmitry Dubrova | 21ce86003b | |
Dzmitry Dubrova | 83b43363fa | |
¥IGA | e603165e2b | |
Dzmitry Dubrova | 7766a653d5 | |
Dzmitry Dubrova | 3f445eca40 | |
SaynedBread | 41a93dcae4 | |
SaynedBread | 1e90f45941 | |
TheTurtle | c79b10edc1 | |
Vinicius Rangel | 9e4fc17e6c | |
georgemoralis | 208575d392 | |
georgemoralis | 8b0fd59149 | |
Vladislav Mikhalin | 41dec15869 | |
Exhigh | 6a84f6e188 | |
Herman Semenov | 243fd0be78 | |
Random | fc745ee767 | |
psucien | 2c540fbecb | |
georgemoralis | 0b3a88cf22 | |
Matthew Wells | 0ed4614464 | |
georgemoralis | 9852f95c58 | |
georgemoralis | df03783948 | |
¥IGA | 0c5b91e1fb | |
Herman Semenov | a0774c0e87 | |
Alexandre Bouvier | a71d0d8dbb | |
georgemoralis | fda2fdae69 | |
Exhigh | 6545b09b74 | |
georgemoralis | bce3a9c9e7 | |
georgemoralis | 3310fd9a1f | |
georgemoralis | 3e8d7c2040 | |
Xphalnos | d4be3dbb31 | |
georgemoralis | 83bcced16c | |
georgemoralis | 746559658c | |
georgemoralis | 12a65e3fb8 | |
georgemoralis | 834a25fa2b | |
Herman Semenov | aed9a737d6 | |
Aiden Turner | ca4b520272 | |
Vladislav Mikhalin | 79680c50c0 | |
georgemoralis | dfd305ff77 | |
Sebastian Kassai | ba0a6ab038 | |
georgemoralis | 132ca9c5a8 | |
georgemoralis | 3426ad8cc0 | |
Dzmitry Dubrova | 6d0d2eaa59 | |
squidbus | 9275b0966e | |
Borchev | fc300b5265 | |
Borchev | 6596fe091c | |
georgemoralis | 958db559c6 | |
TheTurtle | 3f9c86ad33 | |
Lizardy | 32cb3649d3 | |
xezrunner | 42c4d8353a | |
jdp_ | 6080649b7c | |
jdp_ | 34a1339a2b | |
jdp_ | e070dab2f0 | |
kotn3l | c60bfbe2a5 | |
georgemoralis | 95c89ca6a9 | |
georgemoralis | 8d90e6d997 | |
bax-cz | 0b3356bd1a | |
bax-cz | 8f7b3c2e8c | |
Random | 09da94b7b2 | |
¥IGA | 9d45b99171 | |
Dzmitry Dubrova | 1f416134e7 | |
bax-cz | 516a3e7104 | |
Lizardy | 138c9ce787 | |
georgemoralis | 360b7e1d71 | |
DanielSvoboda | d5e978c6f2 | |
georgemoralis | 09b71a9a3f | |
DanielSvoboda | c58ad6d3b5 | |
DanielSvoboda | c9a502b31a | |
georgemoralis | 5551c61000 | |
DanielSvoboda | ed96a9fb8e | |
DanielSvoboda | 5891900c6e | |
Vladislav Mikhalin | 1c898d0842 | |
Xphalnos | 70576035b0 | |
Leonardo | 14947232a7 | |
Leonardo | 0d56be629b | |
Leonardo | 4375e6fa3a | |
Leonardo | ddec111da6 |
|
@ -19,8 +19,12 @@ chmod a+x linuxdeploy-x86_64.AppImage
|
||||||
chmod a+x linuxdeploy-plugin-qt-x86_64.AppImage
|
chmod a+x linuxdeploy-plugin-qt-x86_64.AppImage
|
||||||
chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
|
chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
|
||||||
|
|
||||||
|
|
||||||
# Build AppImage
|
# Build AppImage
|
||||||
./linuxdeploy-x86_64.AppImage --appdir AppDir
|
./linuxdeploy-x86_64.AppImage --appdir AppDir
|
||||||
./linuxdeploy-plugin-checkrt-x86_64.sh --appdir AppDir
|
./linuxdeploy-plugin-checkrt-x86_64.sh --appdir AppDir
|
||||||
|
|
||||||
|
cp -a "$GITHUB_WORKSPACE/build/translations" AppDir/usr/bin
|
||||||
|
|
||||||
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --plugin qt --output appimage
|
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --plugin qt --output appimage
|
||||||
mv Shadps4-x86_64.AppImage Shadps4-qt.AppImage
|
mv Shadps4-x86_64.AppImage Shadps4-qt.AppImage
|
||||||
|
|
|
@ -23,7 +23,7 @@ jobs:
|
||||||
|
|
||||||
- name: Install misc packages
|
- name: Install misc packages
|
||||||
run: >
|
run: >
|
||||||
sudo apt-get update && sudo apt install libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-dev
|
sudo apt-get update && sudo apt install libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=ON
|
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=ON
|
||||||
|
|
|
@ -38,7 +38,7 @@ jobs:
|
||||||
host: mac
|
host: mac
|
||||||
target: desktop
|
target: desktop
|
||||||
arch: clang_64
|
arch: clang_64
|
||||||
archives: qtbase
|
archives: qtbase qttools
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DENABLE_QT_GUI=ON
|
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DENABLE_QT_GUI=ON
|
||||||
|
@ -50,6 +50,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
mv ${{github.workspace}}/build/shadps4.app upload
|
mv ${{github.workspace}}/build/shadps4.app upload
|
||||||
|
mv ${{github.workspace}}/build/translations upload
|
||||||
macdeployqt upload/shadps4.app
|
macdeployqt upload/shadps4.app
|
||||||
tar cf shadps4-macos-qt.tar.gz -C upload .
|
tar cf shadps4-macos-qt.tar.gz -C upload .
|
||||||
|
|
||||||
|
|
|
@ -43,10 +43,10 @@ jobs:
|
||||||
mv ${{github.workspace}}/build/shadps4 upload
|
mv ${{github.workspace}}/build/shadps4 upload
|
||||||
cp $(arch -x86_64 /usr/local/bin/brew --prefix)/opt/molten-vk/lib/libMoltenVK.dylib upload
|
cp $(arch -x86_64 /usr/local/bin/brew --prefix)/opt/molten-vk/lib/libMoltenVK.dylib upload
|
||||||
install_name_tool -add_rpath "@loader_path" upload/shadps4
|
install_name_tool -add_rpath "@loader_path" upload/shadps4
|
||||||
tar cf shadps4-macos.tar.gz -C upload .
|
tar cf shadps4-macos-sdl.tar.gz -C upload .
|
||||||
|
|
||||||
- name: Upload executable
|
- name: Upload executable
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: shadps4-macos
|
name: shadps4-macos-sdl
|
||||||
path: shadps4-macos.tar.gz
|
path: shadps4-macos-sdl.tar.gz
|
||||||
|
|
|
@ -28,7 +28,7 @@ jobs:
|
||||||
host: windows
|
host: windows
|
||||||
target: desktop
|
target: desktop
|
||||||
arch: win64_msvc2019_64
|
arch: win64_msvc2019_64
|
||||||
archives: qtbase
|
archives: qtbase qttools
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -T ClangCL -DENABLE_QT_GUI=ON
|
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -T ClangCL -DENABLE_QT_GUI=ON
|
||||||
|
@ -40,6 +40,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
move build/Release/shadPS4.exe upload
|
move build/Release/shadPS4.exe upload
|
||||||
|
move build/translations upload
|
||||||
windeployqt --dir upload upload/shadPS4.exe
|
windeployqt --dir upload upload/shadPS4.exe
|
||||||
|
|
||||||
- name: Upload executable
|
- name: Upload executable
|
||||||
|
|
|
@ -29,6 +29,6 @@ jobs:
|
||||||
- name: Upload executable
|
- name: Upload executable
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: shadps4-win64
|
name: shadps4-win64-sdl
|
||||||
path: |
|
path: |
|
||||||
${{github.workspace}}/build/Release/shadPS4.exe
|
${{github.workspace}}/build/Release/shadPS4.exe
|
||||||
|
|
|
@ -1,66 +1,87 @@
|
||||||
[submodule "externals/discord-rpc"]
|
|
||||||
path = externals/discord-rpc
|
|
||||||
url = https://github.com/shadps4-emu/ext-discord-rpc.git
|
|
||||||
[submodule "externals/cryptopp-cmake"]
|
[submodule "externals/cryptopp-cmake"]
|
||||||
path = externals/cryptopp-cmake
|
path = externals/cryptopp-cmake
|
||||||
url = https://github.com/shadps4-emu/ext-cryptopp-cmake.git
|
url = https://github.com/shadps4-emu/ext-cryptopp-cmake.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/cryptopp"]
|
[submodule "externals/cryptopp"]
|
||||||
path = externals/cryptopp
|
path = externals/cryptopp
|
||||||
url = https://github.com/shadps4-emu/ext-cryptopp.git
|
url = https://github.com/shadps4-emu/ext-cryptopp.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/cryptoppwin"]
|
[submodule "externals/cryptoppwin"]
|
||||||
path = externals/cryptoppwin
|
path = externals/cryptoppwin
|
||||||
url = https://github.com/shadps4-emu/ext-cryptoppwin.git
|
url = https://github.com/shadps4-emu/ext-cryptoppwin.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/zlib-ng"]
|
[submodule "externals/zlib-ng"]
|
||||||
path = externals/zlib-ng
|
path = externals/zlib-ng
|
||||||
url = https://github.com/shadps4-emu/ext-zlib-ng.git
|
url = https://github.com/shadps4-emu/ext-zlib-ng.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/sdl3"]
|
[submodule "externals/sdl3"]
|
||||||
path = externals/sdl3
|
path = externals/sdl3
|
||||||
url = https://github.com/shadps4-emu/ext-SDL.git
|
url = https://github.com/shadps4-emu/ext-SDL.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/fmt"]
|
[submodule "externals/fmt"]
|
||||||
path = externals/fmt
|
path = externals/fmt
|
||||||
url = https://github.com/shadps4-emu/ext-fmt.git
|
url = https://github.com/shadps4-emu/ext-fmt.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/vulkan-headers"]
|
[submodule "externals/vulkan-headers"]
|
||||||
path = externals/vulkan-headers
|
path = externals/vulkan-headers
|
||||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/vma"]
|
[submodule "externals/vma"]
|
||||||
path = externals/vma
|
path = externals/vma
|
||||||
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/glslang"]
|
[submodule "externals/glslang"]
|
||||||
path = externals/glslang
|
path = externals/glslang
|
||||||
url = https://github.com/KhronosGroup/glslang.git
|
url = https://github.com/KhronosGroup/glslang.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/robin-map"]
|
[submodule "externals/robin-map"]
|
||||||
path = externals/robin-map
|
path = externals/robin-map
|
||||||
url = https://github.com/Tessil/robin-map.git
|
url = https://github.com/Tessil/robin-map.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/xbyak"]
|
[submodule "externals/xbyak"]
|
||||||
path = externals/xbyak
|
path = externals/xbyak
|
||||||
url = https://github.com/herumi/xbyak.git
|
url = https://github.com/herumi/xbyak.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/winpthreads"]
|
[submodule "externals/winpthreads"]
|
||||||
path = externals/winpthreads
|
path = externals/winpthreads
|
||||||
url = https://github.com/shadps4-emu/winpthreads.git
|
url = https://github.com/shadps4-emu/winpthreads.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/magic_enum"]
|
[submodule "externals/magic_enum"]
|
||||||
path = externals/magic_enum
|
path = externals/magic_enum
|
||||||
url = https://github.com/Neargye/magic_enum.git
|
url = https://github.com/Neargye/magic_enum.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/toml11"]
|
[submodule "externals/toml11"]
|
||||||
path = externals/toml11
|
path = externals/toml11
|
||||||
url = https://github.com/ToruNiina/toml11.git
|
url = https://github.com/ToruNiina/toml11.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/zydis"]
|
[submodule "externals/zydis"]
|
||||||
path = externals/zydis
|
path = externals/zydis
|
||||||
url = https://github.com/zyantific/zydis.git
|
url = https://github.com/zyantific/zydis.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/sirit"]
|
[submodule "externals/sirit"]
|
||||||
path = externals/sirit
|
path = externals/sirit
|
||||||
url = https://github.com/shadps4-emu/sirit.git
|
url = https://github.com/shadps4-emu/sirit.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/xxhash"]
|
[submodule "externals/xxhash"]
|
||||||
path = externals/xxhash
|
path = externals/xxhash
|
||||||
url = https://github.com/Cyan4973/xxHash.git
|
url = https://github.com/Cyan4973/xxHash.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/tracy"]
|
[submodule "externals/tracy"]
|
||||||
path = externals/tracy
|
path = externals/tracy
|
||||||
url = https://github.com/shadps4-emu/tracy.git
|
url = https://github.com/shadps4-emu/tracy.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/ext-boost"]
|
[submodule "externals/ext-boost"]
|
||||||
path = externals/ext-boost
|
path = externals/ext-boost
|
||||||
url = https://github.com/shadps4-emu/ext-boost.git
|
url = https://github.com/shadps4-emu/ext-boost.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/date"]
|
[submodule "externals/date"]
|
||||||
path = externals/date
|
path = externals/date
|
||||||
url = https://github.com/HowardHinnant/date.git
|
url = https://github.com/HowardHinnant/date.git
|
||||||
|
shallow = true
|
||||||
[submodule "externals/ffmpeg-core"]
|
[submodule "externals/ffmpeg-core"]
|
||||||
path = externals/ffmpeg-core
|
path = externals/ffmpeg-core
|
||||||
url = https://github.com/shadps4-emu/ext-ffmpeg-core
|
url = https://github.com/shadps4-emu/ext-ffmpeg-core.git
|
||||||
|
shallow = true
|
||||||
|
[submodule "externals/half"]
|
||||||
|
path = externals/half
|
||||||
|
url = https://github.com/ROCm/half.git
|
||||||
|
|
|
@ -15,6 +15,7 @@ Files: CMakeSettings.json
|
||||||
documents/Screenshots/Undertale.png
|
documents/Screenshots/Undertale.png
|
||||||
documents/Screenshots/We are DOOMED.png
|
documents/Screenshots/We are DOOMED.png
|
||||||
scripts/ps4_names.txt
|
scripts/ps4_names.txt
|
||||||
|
src/images/about_icon.png
|
||||||
src/images/controller_icon.png
|
src/images/controller_icon.png
|
||||||
src/images/exit_icon.png
|
src/images/exit_icon.png
|
||||||
src/images/file_icon.png
|
src/images/file_icon.png
|
||||||
|
|
103
CMakeLists.txt
103
CMakeLists.txt
|
@ -66,21 +66,24 @@ git_branch_name(GIT_BRANCH)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp" @ONLY)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||||
|
|
||||||
find_package(Boost 1.84.0 CONFIG)
|
find_package(Boost 1.84.0 CONFIG)
|
||||||
find_package(cryptopp 8.9.0 MODULE)
|
|
||||||
find_package(FFmpeg 5.1.2 MODULE)
|
find_package(FFmpeg 5.1.2 MODULE)
|
||||||
find_package(fmt 10.2.1 CONFIG)
|
find_package(fmt 10.2.0 CONFIG)
|
||||||
find_package(glslang 14.2.0 CONFIG)
|
find_package(glslang 14.2.0 CONFIG)
|
||||||
find_package(magic_enum 0.9.6 CONFIG)
|
find_package(magic_enum 0.9.6 CONFIG)
|
||||||
find_package(RenderDoc 1.6.0 MODULE)
|
find_package(RenderDoc 1.6.0 MODULE)
|
||||||
find_package(SDL3 3.1.2 CONFIG)
|
find_package(SDL3 3.1.2 CONFIG)
|
||||||
find_package(toml11 3.8.1 CONFIG)
|
find_package(toml11 4.2.0 CONFIG)
|
||||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||||
find_package(VulkanHeaders 1.3.289 CONFIG)
|
find_package(VulkanHeaders 1.3.289 CONFIG)
|
||||||
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
||||||
find_package(xbyak 7.07 CONFIG)
|
find_package(xbyak 7.07 CONFIG)
|
||||||
find_package(xxHash 0.8.2 MODULE)
|
find_package(xxHash 0.8.2 MODULE)
|
||||||
find_package(zlib-ng 2.2.0 MODULE)
|
find_package(zlib-ng 2.1.7 MODULE)
|
||||||
find_package(Zydis 4.1.0 CONFIG)
|
find_package(Zydis 5.0.0 CONFIG)
|
||||||
|
|
||||||
|
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR NOT MSVC)
|
||||||
|
find_package(cryptopp 8.9.0 MODULE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
find_package(date 3.0.1 CONFIG)
|
find_package(date 3.0.1 CONFIG)
|
||||||
|
@ -92,10 +95,6 @@ check_symbol_exists(pthread_mutex_timedlock "pthread.h" HAVE_PTHREAD_MUTEX_TIMED
|
||||||
if(HAVE_PTHREAD_MUTEX_TIMEDLOCK OR WIN32)
|
if(HAVE_PTHREAD_MUTEX_TIMEDLOCK OR WIN32)
|
||||||
add_compile_options(-DHAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
add_compile_options(-DHAVE_PTHREAD_MUTEX_TIMEDLOCK)
|
||||||
endif()
|
endif()
|
||||||
check_symbol_exists(sem_timedwait "semaphore.h" HAVE_SEM_TIMEDWAIT)
|
|
||||||
if(HAVE_SEM_TIMEDWAIT OR WIN32)
|
|
||||||
add_compile_options(-DHAVE_SEM_TIMEDWAIT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||||
# libc++ requires -fexperimental-library to enable std::jthread and std::stop_token support.
|
# libc++ requires -fexperimental-library to enable std::jthread and std::stop_token support.
|
||||||
|
@ -110,11 +109,27 @@ add_subdirectory(externals)
|
||||||
include_directories(src)
|
include_directories(src)
|
||||||
|
|
||||||
if(ENABLE_QT_GUI)
|
if(ENABLE_QT_GUI)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent)
|
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent LinguistTools Network)
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
set(CMAKE_AUTORCC ON)
|
set(CMAKE_AUTORCC ON)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
set(CMAKE_AUTOUIC ON)
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
|
||||||
|
set(QT_TRANSLATIONS "${PROJECT_SOURCE_DIR}/src/qt_gui/translations")
|
||||||
|
file(GLOB_RECURSE TRANSLATIONS_TS ${QT_TRANSLATIONS}/*.ts)
|
||||||
|
|
||||||
|
set_source_files_properties(${TRANSLATIONS_TS} PROPERTIES OUTPUT_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/translations")
|
||||||
|
qt_add_translation(TRANSLATIONS_QM ${TRANSLATIONS_TS})
|
||||||
|
|
||||||
|
set(TRANSLATIONS_QRC ${CMAKE_CURRENT_BINARY_DIR}/translations/translations.qrc)
|
||||||
|
file(WRITE ${TRANSLATIONS_QRC} "<RCC><qresource prefix=\"translations\">\n")
|
||||||
|
foreach (QM ${TRANSLATIONS_QM})
|
||||||
|
get_filename_component(QM_FILE ${QM} NAME)
|
||||||
|
file(APPEND ${TRANSLATIONS_QRC} "<file>${QM_FILE}</file>\n")
|
||||||
|
endforeach (QM)
|
||||||
|
file(APPEND ${TRANSLATIONS_QRC} "</qresource></RCC>")
|
||||||
|
|
||||||
|
qt_add_resources(TRANSLATIONS ${TRANSLATIONS_QRC})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(AUDIO_CORE src/audio_core/sdl_audio.cpp
|
set(AUDIO_CORE src/audio_core/sdl_audio.cpp
|
||||||
|
@ -127,10 +142,13 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
|
||||||
src/core/libraries/audio/audioout.h
|
src/core/libraries/audio/audioout.h
|
||||||
src/core/libraries/ajm/ajm.cpp
|
src/core/libraries/ajm/ajm.cpp
|
||||||
src/core/libraries/ajm/ajm.h
|
src/core/libraries/ajm/ajm.h
|
||||||
|
src/core/libraries/ngs2/ngs2.cpp
|
||||||
|
src/core/libraries/ngs2/ngs2.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
||||||
src/core/libraries/gnmdriver/gnmdriver.h
|
src/core/libraries/gnmdriver/gnmdriver.h
|
||||||
|
src/core/libraries/gnmdriver/gnm_error.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(KERNEL_LIB
|
set(KERNEL_LIB
|
||||||
|
@ -191,6 +209,7 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||||
src/core/libraries/app_content/app_content.h
|
src/core/libraries/app_content/app_content.h
|
||||||
src/core/libraries/rtc/rtc.cpp
|
src/core/libraries/rtc/rtc.cpp
|
||||||
src/core/libraries/rtc/rtc.h
|
src/core/libraries/rtc/rtc.h
|
||||||
|
src/core/libraries/rtc/rtc_error.h
|
||||||
src/core/libraries/disc_map/disc_map.cpp
|
src/core/libraries/disc_map/disc_map.cpp
|
||||||
src/core/libraries/disc_map/disc_map.h
|
src/core/libraries/disc_map/disc_map.h
|
||||||
src/core/libraries/disc_map/disc_map_codes.h
|
src/core/libraries/disc_map/disc_map_codes.h
|
||||||
|
@ -206,6 +225,12 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||||
src/core/libraries/avplayer/avplayer_state.h
|
src/core/libraries/avplayer/avplayer_state.h
|
||||||
src/core/libraries/avplayer/avplayer.cpp
|
src/core/libraries/avplayer/avplayer.cpp
|
||||||
src/core/libraries/avplayer/avplayer.h
|
src/core/libraries/avplayer/avplayer.h
|
||||||
|
src/core/libraries/ngs2/ngs2.cpp
|
||||||
|
src/core/libraries/ngs2/ngs2.h
|
||||||
|
src/core/libraries/ngs2/ngs2_error.h
|
||||||
|
src/core/libraries/ngs2/ngs2_impl.cpp
|
||||||
|
src/core/libraries/ngs2/ngs2_impl.h
|
||||||
|
src/core/libraries/ajm/ajm_error.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||||
|
@ -215,21 +240,7 @@ set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||||
src/core/libraries/videoout/video_out.h
|
src/core/libraries/videoout/video_out.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBC_SOURCES src/core/libraries/libc/libc.cpp
|
set(LIBC_SOURCES src/core/libraries/libc_internal/libc_internal.cpp
|
||||||
src/core/libraries/libc/libc.h
|
|
||||||
src/core/libraries/libc/printf.h
|
|
||||||
src/core/libraries/libc/va_ctx.h
|
|
||||||
src/core/libraries/libc/libc_cxa.cpp
|
|
||||||
src/core/libraries/libc/libc_cxa.h
|
|
||||||
src/core/libraries/libc/libc_stdio.cpp
|
|
||||||
src/core/libraries/libc/libc_stdio.h
|
|
||||||
src/core/libraries/libc/libc_math.cpp
|
|
||||||
src/core/libraries/libc/libc_math.h
|
|
||||||
src/core/libraries/libc/libc_string.cpp
|
|
||||||
src/core/libraries/libc/libc_string.h
|
|
||||||
src/core/libraries/libc/libc_stdlib.cpp
|
|
||||||
src/core/libraries/libc/libc_stdlib.h
|
|
||||||
src/core/libraries/libc_internal/libc_internal.cpp
|
|
||||||
src/core/libraries/libc_internal/libc_internal.h
|
src/core/libraries/libc_internal/libc_internal.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -255,6 +266,7 @@ set(PLAYGO_LIB src/core/libraries/playgo/playgo.cpp
|
||||||
|
|
||||||
set(RANDOM_LIB src/core/libraries/random/random.cpp
|
set(RANDOM_LIB src/core/libraries/random/random.cpp
|
||||||
src/core/libraries/random/random.h
|
src/core/libraries/random/random.h
|
||||||
|
src/core/libraries/random/random_error.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(USBD_LIB src/core/libraries/usbd/usbd.cpp
|
set(USBD_LIB src/core/libraries/usbd/usbd.cpp
|
||||||
|
@ -268,6 +280,7 @@ set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
||||||
src/core/libraries/np_trophy/np_trophy.cpp
|
src/core/libraries/np_trophy/np_trophy.cpp
|
||||||
src/core/libraries/np_trophy/np_trophy.h
|
src/core/libraries/np_trophy/np_trophy.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
|
set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
|
||||||
src/core/libraries/screenshot/screenshot.h
|
src/core/libraries/screenshot/screenshot.h
|
||||||
)
|
)
|
||||||
|
@ -417,7 +430,6 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||||
src/shader_recompiler/backend/spirv/spirv_emit_context.h
|
src/shader_recompiler/backend/spirv/spirv_emit_context.h
|
||||||
src/shader_recompiler/frontend/translate/data_share.cpp
|
src/shader_recompiler/frontend/translate/data_share.cpp
|
||||||
src/shader_recompiler/frontend/translate/export.cpp
|
src/shader_recompiler/frontend/translate/export.cpp
|
||||||
src/shader_recompiler/frontend/translate/flat_memory.cpp
|
|
||||||
src/shader_recompiler/frontend/translate/scalar_alu.cpp
|
src/shader_recompiler/frontend/translate/scalar_alu.cpp
|
||||||
src/shader_recompiler/frontend/translate/scalar_memory.cpp
|
src/shader_recompiler/frontend/translate/scalar_memory.cpp
|
||||||
src/shader_recompiler/frontend/translate/translate.cpp
|
src/shader_recompiler/frontend/translate/translate.cpp
|
||||||
|
@ -437,7 +449,7 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||||
src/shader_recompiler/frontend/opcodes.h
|
src/shader_recompiler/frontend/opcodes.h
|
||||||
src/shader_recompiler/frontend/structured_control_flow.cpp
|
src/shader_recompiler/frontend/structured_control_flow.cpp
|
||||||
src/shader_recompiler/frontend/structured_control_flow.h
|
src/shader_recompiler/frontend/structured_control_flow.h
|
||||||
src/shader_recompiler/ir/passes/constant_propogation_pass.cpp
|
src/shader_recompiler/ir/passes/constant_propagation_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp
|
src/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/identity_removal_pass.cpp
|
src/shader_recompiler/ir/passes/identity_removal_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/ir_passes.h
|
src/shader_recompiler/ir/passes/ir_passes.h
|
||||||
|
@ -475,6 +487,7 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||||
src/video_core/amdgpu/pm4_cmds.h
|
src/video_core/amdgpu/pm4_cmds.h
|
||||||
src/video_core/amdgpu/pm4_opcodes.h
|
src/video_core/amdgpu/pm4_opcodes.h
|
||||||
src/video_core/amdgpu/resource.h
|
src/video_core/amdgpu/resource.h
|
||||||
|
src/video_core/amdgpu/default_context.cpp
|
||||||
src/video_core/buffer_cache/buffer.cpp
|
src/video_core/buffer_cache/buffer.cpp
|
||||||
src/video_core/buffer_cache/buffer.h
|
src/video_core/buffer_cache/buffer.h
|
||||||
src/video_core/buffer_cache/buffer_cache.cpp
|
src/video_core/buffer_cache/buffer_cache.cpp
|
||||||
|
@ -508,6 +521,8 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||||
src/video_core/renderer_vulkan/vk_resource_pool.h
|
src/video_core/renderer_vulkan/vk_resource_pool.h
|
||||||
src/video_core/renderer_vulkan/vk_scheduler.cpp
|
src/video_core/renderer_vulkan/vk_scheduler.cpp
|
||||||
src/video_core/renderer_vulkan/vk_scheduler.h
|
src/video_core/renderer_vulkan/vk_scheduler.h
|
||||||
|
src/video_core/renderer_vulkan/vk_shader_cache.cpp
|
||||||
|
src/video_core/renderer_vulkan/vk_shader_cache.h
|
||||||
src/video_core/renderer_vulkan/vk_shader_util.cpp
|
src/video_core/renderer_vulkan/vk_shader_util.cpp
|
||||||
src/video_core/renderer_vulkan/vk_shader_util.h
|
src/video_core/renderer_vulkan/vk_shader_util.h
|
||||||
src/video_core/renderer_vulkan/vk_swapchain.cpp
|
src/video_core/renderer_vulkan/vk_swapchain.cpp
|
||||||
|
@ -550,6 +565,10 @@ qt_add_resources(RESOURCE_FILES src/shadps4.qrc)
|
||||||
set(QT_GUI src/qt_gui/about_dialog.cpp
|
set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||||
src/qt_gui/about_dialog.h
|
src/qt_gui/about_dialog.h
|
||||||
src/qt_gui/about_dialog.ui
|
src/qt_gui/about_dialog.ui
|
||||||
|
src/qt_gui/cheats_patches.cpp
|
||||||
|
src/qt_gui/cheats_patches.h
|
||||||
|
src/qt_gui/memory_patcher.cpp
|
||||||
|
src/qt_gui/memory_patcher.h
|
||||||
src/qt_gui/main_window_ui.h
|
src/qt_gui/main_window_ui.h
|
||||||
src/qt_gui/main_window.cpp
|
src/qt_gui/main_window.cpp
|
||||||
src/qt_gui/main_window.h
|
src/qt_gui/main_window.h
|
||||||
|
@ -577,6 +596,7 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||||
src/qt_gui/main.cpp
|
src/qt_gui/main.cpp
|
||||||
${EMULATOR}
|
${EMULATOR}
|
||||||
${RESOURCE_FILES}
|
${RESOURCE_FILES}
|
||||||
|
${TRANSLATIONS}
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -624,6 +644,9 @@ if (APPLE)
|
||||||
|
|
||||||
# Replacement for std::chrono::time_zone
|
# Replacement for std::chrono::time_zone
|
||||||
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
target_link_libraries(shadps4 PRIVATE date::date-tz)
|
||||||
|
|
||||||
|
# Half float conversions for F16C patches
|
||||||
|
target_link_libraries(shadps4 PRIVATE half)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT ENABLE_QT_GUI)
|
if (NOT ENABLE_QT_GUI)
|
||||||
|
@ -637,27 +660,45 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_QT_GUI)
|
if (ENABLE_QT_GUI)
|
||||||
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent)
|
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network)
|
||||||
|
add_definitions(-DENABLE_QT_GUI)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(shadps4 PRIVATE mincore winpthreads clang_rt.builtins-x86_64.lib)
|
target_link_libraries(shadps4 PRIVATE mincore winpthreads)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# MSVC likes putting opinions on what people can use, disable:
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
||||||
|
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# Needed for conflicts with time.h of windows.h
|
# Needed for conflicts with time.h of windows.h
|
||||||
add_definitions(-D_TIMESPEC_DEFINED)
|
add_definitions(-D_TIMESPEC_DEFINED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Target Windows 10 RS5
|
# Target Windows 10 RS5
|
||||||
add_definitions(-DNTDDI_VERSION=0x0A000006 -D_WIN32_WINNT=0x0A00 -DWINVER=0x0A00)
|
add_definitions(-DNTDDI_VERSION=0x0A000006 -D_WIN32_WINNT=0x0A00 -DWINVER=0x0A00)
|
||||||
# Increase stack commit area
|
|
||||||
target_link_options(shadps4 PRIVATE /STACK:0x200000,0x200000)
|
if (MSVC)
|
||||||
|
target_link_libraries(shadps4 PRIVATE clang_rt.builtins-x86_64.lib)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Disable ASLR so we can reserve the user area
|
# Disable ASLR so we can reserve the user area
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
target_link_options(shadps4 PRIVATE /DYNAMICBASE:NO)
|
target_link_options(shadps4 PRIVATE /DYNAMICBASE:NO)
|
||||||
else()
|
else()
|
||||||
target_link_options(shadps4 PRIVATE -Wl,--disable-dynamicbase)
|
target_link_options(shadps4 PRIVATE -Wl,--disable-dynamicbase)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Increase stack commit area (Needed, otherwise there are crashes)
|
||||||
|
if (MSVC)
|
||||||
|
target_link_options(shadps4 PRIVATE /STACK:0x200000,0x200000)
|
||||||
|
else()
|
||||||
|
target_link_options(shadps4 PRIVATE -Wl,--stack,2097152)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
|
@ -69,7 +69,7 @@ enum class SomeEnum {
|
||||||
* Note that the asterisks are indented by one space to align to the first line.
|
* Note that the asterisks are indented by one space to align to the first line.
|
||||||
*/
|
*/
|
||||||
struct Position {
|
struct Position {
|
||||||
// Always intitialize member variables!
|
// Always initialize member variables!
|
||||||
int x{};
|
int x{};
|
||||||
int y{};
|
int y{};
|
||||||
};
|
};
|
||||||
|
|
30
README.md
30
README.md
|
@ -32,27 +32,30 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
<img src="https://github.com/shadps4-emu/shadPS4/blob/main/documents/Screenshots/We are DOOMED.png" width="400">
|
<img src="https://github.com/shadps4-emu/shadPS4/blob/main/documents/Screenshots/We are DOOMED.png" width="400">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
# shadPS4
|
# General information
|
||||||
|
|
||||||
shadPS4 is an early **PlayStation 4** emulator for **Windows**, **Linux** and **macOS** written in C++
|
shadPS4 is an early **PlayStation 4** emulator for **Windows**, **Linux** and **macOS** written in C++.
|
||||||
|
|
||||||
If you encounter problems or have doubts, do not hesitate to look at the [**Quickstart**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Quickstart/Quickstart.md).
|
If you encounter problems or have doubts, do not hesitate to look at the [**Quickstart**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Quickstart/Quickstart.md).
|
||||||
|
|
||||||
To verify that a game works, you can look at [**shadPS4 Game Compatibility**](https://github.com/shadps4-emu/shadps4-game-compatibility).
|
To verify that a game works, you can look at [**shadPS4 Game Compatibility**](https://github.com/shadps4-emu/shadps4-game-compatibility).
|
||||||
|
|
||||||
To discuss shadPS4 development or suggest ideas, join the [**Discord server**](https://discord.gg/MyZRaBngxA).
|
To discuss shadPS4 development, suggest ideas or to ask for help, join our [**Discord server**](https://discord.gg/MyZRaBngxA).
|
||||||
|
|
||||||
To get the latest news, go to our [**X (twitter)**](https://x.com/shadps4) or our [**website**](https://shadps4.net/).
|
To get the latest news, go to our [**X (Twitter)**](https://x.com/shadps4) or our [**website**](https://shadps4.net/).
|
||||||
|
|
||||||
# Status
|
# Status
|
||||||
|
|
||||||
In development, small games are working like [**Sonic Mania**](https://www.youtube.com/watch?v=AAHoNzhHyCU), [**Undertale**](https://youtu.be/5zIvdy65Ro4), [**Dysmantle**](https://youtu.be/b9xzhLBdESE) and others...
|
> [!IMPORTANT]
|
||||||
|
> shadPS4 is early in developement, don't expect a flawless experience.
|
||||||
|
|
||||||
|
Currently, the emulator successfully runs small games like [**Sonic Mania**](https://www.youtube.com/watch?v=AAHoNzhHyCU), [**Undertale**](https://youtu.be/5zIvdy65Ro4) and it can even *somewhat* run [**Bloodborne**](https://www.youtube.com/watch?v=wC6s0avpQRE).
|
||||||
|
|
||||||
# Why
|
# Why
|
||||||
|
|
||||||
The project started as a fun project. Due to limited free time, it will probably take a while before shadPS4 is able to run anything decent, but we're trying to make small, regular commits.
|
This project began as a fun project. Given our limited free time, it may take some time before shadPS4 can run more complex games, but we're committed to making small, regular updates.
|
||||||
|
|
||||||
# Build
|
# Building
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
|
@ -62,7 +65,7 @@ Check the build instructions for [**Windows**](https://github.com/shadps4-emu/sh
|
||||||
|
|
||||||
Check the build instructions for [**Linux**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-linux.md).
|
Check the build instructions for [**Linux**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-linux.md).
|
||||||
|
|
||||||
## Build status
|
## Building status
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary><b>Windows</b></summary>
|
<summary><b>Windows</b></summary>
|
||||||
|
@ -91,9 +94,16 @@ Check the build instructions for [**Linux**](https://github.com/shadps4-emu/shad
|
||||||
|macOS Qt Build|[![macOS-qt](https://github.com/shadps4-emu/shadPS4/actions/workflows/macos-qt.yml/badge.svg)](https://github.com/shadps4-emu/shadPS4/actions/workflows/macos-qt.yml)
|
|macOS Qt Build|[![macOS-qt](https://github.com/shadps4-emu/shadPS4/actions/workflows/macos-qt.yml/badge.svg)](https://github.com/shadps4-emu/shadPS4/actions/workflows/macos-qt.yml)
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
# Keyboard Mapping
|
# Debugging and reporting issues
|
||||||
|
|
||||||
| Controller button | Keyboard |
|
For more information on how to test, debug and report issues with the emulator or games, read the [Debugging documentation](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Debugging/Debugging.md).
|
||||||
|
|
||||||
|
# Keyboard mapping
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Xbox and DualShock controllers work out of the box.
|
||||||
|
|
||||||
|
| Controller button | Keyboard equivelant |
|
||||||
|-------------|-------------|
|
|-------------|-------------|
|
||||||
LEFT AXIS UP | W |
|
LEFT AXIS UP | W |
|
||||||
LEFT AXIS DOWN | S |
|
LEFT AXIS DOWN | S |
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project
|
||||||
|
SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
-->
|
||||||
|
|
||||||
|
# Debugging and reporting issues about shadPS4 and games
|
||||||
|
|
||||||
|
This document covers information about debugging, troubleshooting and reporting developer-side issues related to shadPS4 and games.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
This section will guide you through setting up tools for debugging the emulator. This list will likely expand as more tools and platforms receive consistent setups.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Windows and Visual Studio</summary>
|
||||||
|
|
||||||
|
Make sure you have the project set up for building on Windows with Visual Studio and CMake: [Build shadPS4 for Windows
|
||||||
|
](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-windows.md)
|
||||||
|
|
||||||
|
1. Open the project folder in Visual Studio **as a folder**. _Do not run `cmake ..` or other commands that set up the project._
|
||||||
|
|
||||||
|
2. In the Solution Explorer, click the **Switch between solutions and available views** button.\
|
||||||
|
![image](https://github.com/user-attachments/assets/4e2be2b1-ba5a-4451-9ab2-f4ecf246213d)
|
||||||
|
|
||||||
|
3. Double-click on **CMake Targets View**.\
|
||||||
|
![image](https://github.com/user-attachments/assets/5ce7cf90-cd61-4cfa-bef5-645909827290)
|
||||||
|
|
||||||
|
4. Under **shadPS4 Project**, right-click on the **shadps4 (executable)** solution and click **Set as Startup Item**. This will let you start and debug shadPS4 using the VS debug buttons, as well as the default F5 shortcut.\
|
||||||
|
![image](https://github.com/user-attachments/assets/34c7c047-28a3-499f-be8f-df781134d104)
|
||||||
|
|
||||||
|
5. Right-click the **shadps4 (executable)** solution once more and click **Add debug configuration**.
|
||||||
|
|
||||||
|
6. Add an `"args: []"` section into the first `configurations` entry.\
|
||||||
|
List your game path as an argument, as if you were launching the non-GUI emulator from the command line.
|
||||||
|
![image](https://github.com/user-attachments/assets/8c7c3e69-f38f-4d6b-bdfd-4f1c41c50be7)
|
||||||
|
|
||||||
|
7. Set the appropriate CMake configuration for debugging or testing.
|
||||||
|
- For debugging the emulator and games within it, select `x64-Clang-Debug`.
|
||||||
|
- For testing the emulator with compiler optimizations as a release build, it is recommended to select `x64-Clang-RelWithDebInfo`,
|
||||||
|
as debug symbols will still be generated in case you encounter release configuration-exclusive bugs/errors.
|
||||||
|
![image](https://github.com/user-attachments/assets/0d975f7a-7bea-4f89-87ef-5d685bea4381)
|
||||||
|
|
||||||
|
Launch and debug the emulator through **Debug > Start Debugging** (F5 by default), or **Debug > Start Without Debugging** (Ctrl+F5 by default) when testing games for performance.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
You can configure the emulator by editing the `config.toml` file found in the `user` folder created after starting the application.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Some configuration entries worth changing</summary>
|
||||||
|
|
||||||
|
- `[General]`
|
||||||
|
|
||||||
|
- `logType`: Configures logging synchronization (`sync`/`async`)
|
||||||
|
- By default, the emulator logs messages asynchronously for better performance. Some log messages may end up being received out-of-order.
|
||||||
|
- It can be beneficial to set this to `sync` in order for the log to accurately maintain message order, at the cost of performance.
|
||||||
|
- When communicating about issues with games and the log messages aren't clear due to potentially confusing order, set this to `sync` and send that log as well.
|
||||||
|
- `logFilter`: Sets the logging category for various logging classes.
|
||||||
|
- Format: `<class>:<level> ...`
|
||||||
|
- Multiple classes can be set by separating them with a space. (example: `Render:Warning Debug:Critical Lib.Pad:Error`)
|
||||||
|
- Sub-classes can be specified in the same format as seen in the console/log (such as `Core.Linker`).
|
||||||
|
- All classes and sub-classes can be set by specifying a `*` symbol. (example: `Kernel.*:Critical`)
|
||||||
|
- Valid log levels: `Trace, Debug, Info, Warning, Error, Critical` - in this order, setting a level silences all levels preceding it and logs every level after it.
|
||||||
|
- Examples:
|
||||||
|
- If the log is being spammed with messages coming from Lib.Pad, you can use `Lib.Pad:Critical` to only log critical-level messages.
|
||||||
|
- If you'd like to mute everything, but still want to receive messages from Vulkan rendering: `*:Critical Render.Vulkan:Info`
|
||||||
|
|
||||||
|
- `Fullscreen`: Display the game in a full screen borderless window.
|
||||||
|
|
||||||
|
- `[GPU]`
|
||||||
|
- `dumpShaders`: Dump shaders that are loaded by the emulator. Dump path: `../user/shader/dumps`
|
||||||
|
- `nullGpu`: Disables rendering.
|
||||||
|
- `screenWidth` and `screenHeight`: Configures the game window width and height.
|
||||||
|
|
||||||
|
- `[Vulkan]`
|
||||||
|
- `validation`-related settings: Use when debugging Vulkan.
|
||||||
|
- `rdocEnable`: Automatically hook RenderDoc when installed. Useful for debugging shaders and game rendering.
|
||||||
|
- `rdocMarkersEnable`: Enable automatic RenderDoc event annotation
|
||||||
|
|
||||||
|
- `[LLE]`
|
||||||
|
- `libc`: Use LLE with `libc`.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Quick analysis
|
||||||
|
|
||||||
|
This section will provide some preliminary steps to take and tips on what to do when you encounter scenarios that require debugging.
|
||||||
|
|
||||||
|
<details open>
|
||||||
|
<summary>When a game crashes and breaks in the debugger</summary>
|
||||||
|
|
||||||
|
1. Analyze the log
|
||||||
|
- A console will open by default when you launch the emulator. It shows the same log messages that go into the log file found at `<emulator executable>/user/log/shad_log.txt`.
|
||||||
|
|
||||||
|
- It is recommended that you start analyzing the log bottom-up first:
|
||||||
|
- Are there any critical or error-level messages at the end of the log that would point to a reason for the game crashing?
|
||||||
|
- Do any of the last few messages contain information about the game loading files?
|
||||||
|
- Did the game window draw anything on-screen?
|
||||||
|
|
||||||
|
- Continue analyzing the log from the start to see other errors (such as with initialization, memory mapping, linker errors etc.)
|
||||||
|
|
||||||
|
2. Analyze the stack trace
|
||||||
|
- When the emulator is launched through a debugger, it will **break** when an exception or violation is encountered.\
|
||||||
|
_(**breaking** in this context means pausing execution of the program before it continues or stops altogether.
|
||||||
|
Breaks can be intentional as well - these are set with various kinds of **breakpoints**.)_
|
||||||
|
|
||||||
|
- Default setups of most debuggers include a **Stack trace** window/panel that lists the functions the program has called before breaking.
|
||||||
|
|
||||||
|
- The stack trace entries can be navigated to and will show the relevant function, as well as switch to the state that the program was in at the time of execution.\
|
||||||
|
Use the **Locals** and **Watch** windows to investigate variables and other code in these contexts.
|
||||||
|
|
||||||
|
3. Identify the reason for the crash
|
||||||
|
- **Logs aren't always accurate in determining the reason for a crash.**\
|
||||||
|
Some log entries are reported as errors but may not be fatal for the execution to stop. `Critical` entries are most likely to be the cause for crashes.
|
||||||
|
|
||||||
|
- Pinpoint the area of the emulator where the crash occured\
|
||||||
|
If the stack trace ends with functions that are relevant to rendering, it is safe to assume that the issue is with **rendering**.\
|
||||||
|
Similarly, if a crash is in a library responsible for playing videos, your issue can be narrowed down to the scope of video playback in the emulator.
|
||||||
|
|
||||||
|
- **⚠ Some crashes are intentional**
|
||||||
|
- If you identify **Access violations for writing operations** where the function is (or in cases of game libraries, _looks like_ it is) copying memory,
|
||||||
|
it most likely is an **intentional exception** meant to catch game data being written by the game.
|
||||||
|
This is used by the emulator developers to identify procedures that have to do with game data changing.
|
||||||
|
- Debugging tools usually include an option to not break on certain types of exceptions. **Exclude access violations and other intentional exceptions when debugging to skip these exceptions.**
|
||||||
|
- You can also identify such cases if the game works in Release builds of the emulator. These intentional exceptions are development-time only.
|
||||||
|
- Attempt to **Continue** and observe whether the stack trace and/or variables and registers change when you encounter exceptions.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
## Reporting and communicating about issues
|
||||||
|
|
||||||
|
When communicating with the project about game-specific issues, specify an **uniquely identifable game name** along with its `CUSA-xxxxx` code that is specific to the region/variant of the game you're testing.\
|
||||||
|
The version number is also important to add at least in the description, especially if you can verify that the game behaves differently across versions.\
|
||||||
|
Accurately identifying games will help other developers that own that game recognize your issue by its title and jump in to help test and debug it.
|
||||||
|
|
||||||
|
- Examples of good naming schemes:
|
||||||
|
- Amplitude (2016) `CUSA02480`
|
||||||
|
- Rock Band 4 (`CUSA02084`) v1.0
|
||||||
|
- inFamous: Second Son \[`CUSA-00004`\]
|
||||||
|
- Examples of unideal naming schemes:
|
||||||
|
- _The Witness_
|
||||||
|
- _GTA 5_
|
||||||
|
- _Watch Dogs_
|
||||||
|
|
||||||
|
- If your issue is small or you aren't sure whether you have properly identified something, [join the Discord server](https://discord.gg/MyZRaBngxA) and use the #development channel
|
||||||
|
to concisely explain the issue, as well as any findings you currently have.
|
||||||
|
|
||||||
|
- It is recommended that you check the [game compatibility issue tracker](https://github.com/shadps4-emu/shadps4-game-compatibility/issues) and post very short summaries of progress changes there,
|
||||||
|
(such as the game now booting into the menu or getting in-game) for organizational and status update purposes.
|
||||||
|
|
||||||
|
- ⚠ **Do not post theoretical, unproven game-specific issues in the emulator issue tracker that you cannot verify and locate in the emulator source code as being a bug.**\
|
||||||
|
Do, however, add information about the game you experienced the issue in, so that it can be tested in a reproducible environment.
|
||||||
|
- Good example: "_Crash in `Shader::Gcn::CFG::EmitBlocks()`, out of bounds list access_" -> _issue description shares stack trace, points to code in the repository and provides relevant information_
|
||||||
|
- Bad example: "_Amplitude crashes on boot, access violation_" -> _issue description reiterates title, focuses on the game instead of the emulator and refuses to elaborate_
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
|
@ -58,4 +58,24 @@ To install PKG files (game and updates), you will need the Qt application (with
|
||||||
|
|
||||||
## Configure the emulator
|
## Configure the emulator
|
||||||
|
|
||||||
You can configure the emulator in the "user" folder (created after the first start of the application) then in the "config.toml" file. Here you can find lots of parameters to set with True or False.
|
You can configure the emulator by editing the `config.toml` file found in the `user` folder created after starting the application.\
|
||||||
|
Some settings may be related to more technical development and debugging. For more information on those, see [Debugging](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Debugging/Debugging.md#configuration).
|
||||||
|
|
||||||
|
Here's a list of configuration entries that are worth changing:
|
||||||
|
|
||||||
|
- `[General]`
|
||||||
|
|
||||||
|
- `Fullscreen`: Display the game in a full screen borderless window.
|
||||||
|
|
||||||
|
- `logType`: Configures logging synchronization (`sync`/`async`)
|
||||||
|
- It can be beneficial to set this to `sync` in order for the log to accurately maintain message order, at the cost of performance.
|
||||||
|
- Use when sending logs to developers. See more about [reporting issues](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Debugging/Debugging.md#reporting-and-communicating-about-issues).
|
||||||
|
- `logFilter`: Sets the logging category for various logging classes.
|
||||||
|
- Format: `<class>:<level> ...`, `<class.*>:<level> <*:level> ...`
|
||||||
|
- Valid log levels: `Trace, Debug, Info, Warning, Error, Critical` - in this order, setting a level silences all levels preceding it and logs every level after it.
|
||||||
|
- Examples:
|
||||||
|
- If the log is being spammed with messages coming from Lib.Pad, you can use `Lib.Pad:Critical` to only log critical-level messages.
|
||||||
|
- If you'd like to mute everything, but still want to receive messages from Vulkan rendering: `*:Error Render.Vulkan:Info`
|
||||||
|
|
||||||
|
- `[GPU]`
|
||||||
|
- `screenWidth` and `screenHeight`: Configures the game window width and height.
|
|
@ -5,21 +5,96 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
# Build shadPS4 for Windows
|
# Build shadPS4 for Windows
|
||||||
|
|
||||||
## Download Visual Studio Community 2022
|
This tutorial reads as if you have none of the prerequisites already installed. If you do, just ignore the steps regarding installation.
|
||||||
|
If you are building to contribute to the project, please omit `--depth 1` from the git invokations.
|
||||||
|
|
||||||
Download link: [**Visual Studio 2022**](https://visualstudio.microsoft.com/vs/)
|
Note: **ARM64 is not supported!** As of writing, it will not build nor run. The instructions with respect to ARM64 are for developers only.
|
||||||
|
|
||||||
## Requirements
|
## Option 1: Visual Studio 2022
|
||||||
|
|
||||||
### From Visual Studio Community
|
### (Prerequisite) Download the Community edition from [**Visual Studio 2022**](https://visualstudio.microsoft.com/vs/)
|
||||||
|
|
||||||
- Desktop development with C++
|
Once you are within the installer:
|
||||||
|
1. Select `Desktop development with C++`
|
||||||
|
2. Go to "Individual Components" tab
|
||||||
|
3. Search and select `C++ Clang Compiler for Windows` and `MSBuild support for LLVM`
|
||||||
|
4. Continue the installation
|
||||||
|
|
||||||
### From individual components tab install
|
### (Prerequisite) Download [**Qt**](https://doc.qt.io/qt-6/get-and-install-qt.html)
|
||||||
|
|
||||||
- C++ Clang Compiler for Windows (17.0.3)
|
Beware, this requires you to create a Qt account. If you do not want to do this, please follow the MSYS2/MinGW compilation method instead.
|
||||||
- MSBuild support for LLVM (Clang-cl) toolset
|
|
||||||
|
|
||||||
- ## Compiling
|
1. Under the current, non beta version of Qt (at the time of writing 6.7.2), select the option `MSVC 2019 64-bit` or similar.
|
||||||
|
If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2019 ARM64` instead.
|
||||||
|
|
||||||
- Open Visual Studio Community and select the **x64-Clang-Release**, **x64-Clang-Debug** or **x64-Clang-RelWithDebInfo**. It should compile just fine.
|
Go through the installation normally. If you know what you are doing, you may unselect individual components that eat up too much disk space.
|
||||||
|
|
||||||
|
2. Download and install [Qt Visual Studio Tools](https://marketplace.visualstudio.com/items?itemName=TheQtCompany.QtVisualStudioTools2022)
|
||||||
|
|
||||||
|
Once you are finished, you will have to configure Qt within Visual Studio:
|
||||||
|
1. Tools -> Options -> Qt -> Versions
|
||||||
|
2. Add a new Qt version and navigate it to the correct folder. Should look like so: `C:\Qt\6.7.2\msvc2019_64`
|
||||||
|
3. Enable the default checkmark on the new version you just created.
|
||||||
|
|
||||||
|
### (Prerequisite) Download [**Git for Windows**](https://git-scm.com/download/win)
|
||||||
|
|
||||||
|
Go through the Git for Windows installation as normal
|
||||||
|
|
||||||
|
### Cloning the source code
|
||||||
|
|
||||||
|
1. Open Git for Windows, navigate to a place where you want to store the shadPS4 source code folder
|
||||||
|
2. Clone the repository by running
|
||||||
|
`git clone --depth 1 --recursive https://github.com/shadps4-emu/shadPS4`
|
||||||
|
|
||||||
|
### Compiling with Visual Studio GUI
|
||||||
|
|
||||||
|
1. Open up Visual Studio, select `Open a local folder` and select the folder with the shadPS4 source code. The folder should contain `CMakeLists.txt`
|
||||||
|
2. Change x64-Clang-Debug to x64-Clang-Release if you want a regular, non-debug build.
|
||||||
|
3. If you want to build shadPS4 with the Qt Gui:
|
||||||
|
1. Click x64-Clang-Release and select "Manage Configurations"
|
||||||
|
2. Look for "CMake command arguments" and add to the text field
|
||||||
|
`-DENABLE_QT_GUI=ON -DCMAKE_PREFIX_PATH=C:\Qt\6.7.2\msvc2019_64`
|
||||||
|
(Change Qt path if you've installed it to non-default path)
|
||||||
|
3. Press CTRL+S to save and wait a moment for CMake generation
|
||||||
|
4. Change the project to build to shadps4.exe
|
||||||
|
5. Build -> Build All
|
||||||
|
|
||||||
|
Your shadps4.exe will be in `c:\path\to\source\Build\x64-Clang-Release\`
|
||||||
|
|
||||||
|
To automatically populate the necessary files to run shadPS4.exe, run in a command prompt or terminal:
|
||||||
|
`C:\Qt\6.7.2\msvc2019_64\bin\windeployqt.exe c:\path\to\shadps4.exe`
|
||||||
|
(Change Qt path if you've installed it to non-default path)
|
||||||
|
|
||||||
|
## Option 2: MSYS2/MinGW
|
||||||
|
|
||||||
|
### (Prerequisite) Download [**MSYS2**](https://www.msys2.org/)
|
||||||
|
|
||||||
|
Go through the MSYS2 installation as normal
|
||||||
|
|
||||||
|
If you are building to distribute, please omit `-DCMAKE_CXX_FLAGS="-O2 -march=native"` within the build configuration step.
|
||||||
|
|
||||||
|
Normal x86-based computers, follow:
|
||||||
|
1. Open "MSYS2 MINGW64" from your new applications
|
||||||
|
2. Run `pacman -Syu`, let it complete;
|
||||||
|
3. Run `pacman -S --needed git mingw-w64-x86_64-binutils mingw-w64-x86_64-clang mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-qt6-base`
|
||||||
|
4. Run `git clone --depth 1 --recursive https://github.com/shadps4-emu/shadPS4`
|
||||||
|
5. Run `cd shadPS4`
|
||||||
|
6. Run `cmake -S . -B build -DCMAKE_CXX_COMPILER="clang++.exe" -DCMAKE_C_COMPILER="clang.exe" -DCMAKE_CXX_FLAGS="-O2 -march=native"`
|
||||||
|
7. Run `cmake --build build`
|
||||||
|
8. To run the finished product, run `./build/shadPS4.exe`
|
||||||
|
|
||||||
|
ARM64-based computers, follow:
|
||||||
|
1. Open "MSYS2 CLANGARM64" from your new applications
|
||||||
|
2. Run `pacman -Syu`, let it complete;
|
||||||
|
3. Run `pacman -S --needed git mingw-w64-clang-aarch64-binutils mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-ninja mingw-w64-clang-aarch64-qt6-base`
|
||||||
|
4. Run `git clone --depth 1 --recursive https://github.com/shadps4-emu/shadPS4`
|
||||||
|
5. Run `cd shadPS4`
|
||||||
|
6. Run `cmake -S . -B build -DCMAKE_CXX_COMPILER="clang++.exe" -DCMAKE_C_COMPILER="clang.exe" -DCMAKE_CXX_FLAGS="-O2 -march=native"`
|
||||||
|
7. Run `cmake --build build`
|
||||||
|
8. To run the finished product, run `./build/shadPS4.exe`
|
||||||
|
|
||||||
|
## Note on MSYS2 builds
|
||||||
|
|
||||||
|
These builds may not be easily copyable to people who do not also have a MSYS2 installation.
|
||||||
|
If you want to distribute these builds, you need to copy over the correct DLLs into a distribution folder.
|
||||||
|
In order to run them, you must be within the MSYS2 shell environment.
|
|
@ -1,3 +1,15 @@
|
||||||
|
v0.2.0 15/08/2024 - codename validptr
|
||||||
|
=================
|
||||||
|
- Adding macOS support
|
||||||
|
- Big shader recompiler improvements
|
||||||
|
- Core improvements
|
||||||
|
- GUI improvements
|
||||||
|
|
||||||
|
v0.1.0 01/07/2024 - codename madturtle
|
||||||
|
=================
|
||||||
|
- Added a shader recompiler, with this we have a lot of games that starts to work
|
||||||
|
- Rewrote a big part of core
|
||||||
|
|
||||||
v0.0.3 23/03/2024 - codename salad
|
v0.0.3 23/03/2024 - codename salad
|
||||||
=================
|
=================
|
||||||
- Switching to std::thread
|
- Switching to std::thread
|
||||||
|
@ -12,21 +24,21 @@ v0.0.3 23/03/2024 - codename salad
|
||||||
- Initial TLS work
|
- Initial TLS work
|
||||||
- New logging implementation
|
- New logging implementation
|
||||||
- Some functions implemented for userService, systemService
|
- Some functions implemented for userService, systemService
|
||||||
-Added sceAudioOut module and output using sdl audio
|
- Added sceAudioOut module and output using SDL audio
|
||||||
|
|
||||||
v0.0.2 21/10/2023
|
v0.0.2 21/10/2023
|
||||||
=================
|
=================
|
||||||
-using cstdint header in variable types
|
- Using cstdint header in variable types
|
||||||
- run_main_entry: Rewrite in asm for stack setup
|
- run_main_entry: Rewrite in asm for stack setup
|
||||||
-printf libc implementation for work with sysv_abi
|
- Printf libc implementation for work with sysv_abi
|
||||||
-initial pad emulation (only digital pad atm)
|
- Initial pad emulation (only digital pad atm)
|
||||||
- Implemented sceVideoOutIsFlipPending
|
- Implemented sceVideoOutIsFlipPending
|
||||||
- Added auto stubs, now unsupported hle function will resolve as empty stubs
|
- Added auto stubs, now unsupported hle function will resolve as empty stubs
|
||||||
- Rewrote libc_cxa functions
|
- Rewrote libc_cxa functions
|
||||||
- Libc implementations ( _ZdlPv,_Znwm,rand,_Fsin,qsort,free,strncpy,memmove,atan2f,pow,_Sin)
|
- Libc implementations ( _ZdlPv,_Znwm,rand,_Fsin,qsort,free,strncpy,memmove,atan2f,pow,_Sin)
|
||||||
-ET_SCE_DYNAMIC behaves as valid for execution now.
|
- ET_SCE_DYNAMIC behaves as valid for execution now
|
||||||
-Initial FileSystem work (not yet usable).
|
- Initial FileSystem work (not yet usable)
|
||||||
|
|
||||||
v0.0.1 29/09/2023
|
v0.0.1 29/09/2023
|
||||||
=================
|
=================
|
||||||
First public release . Everything is new
|
First public release. Everything is new.
|
|
@ -1,35 +0,0 @@
|
||||||
shadPS4 - A PS4 emulator
|
|
||||||
=========================
|
|
||||||
|
|
||||||
1. Intro
|
|
||||||
2. Current status
|
|
||||||
3. Contributors
|
|
||||||
4. Greetings
|
|
||||||
|
|
||||||
1.Intro
|
|
||||||
=======
|
|
||||||
shadPS4 is a Play Station 4 emulator for Windows and Linux. Although atm it can't run a lot of stuff, we are working torwards to make it more compatible.
|
|
||||||
|
|
||||||
2.Current status
|
|
||||||
================
|
|
||||||
shadPS4 is a HLE emulator. Currently on a small amount of functions is emulated, which is one of the reasons compatibility is low.
|
|
||||||
|
|
||||||
3.Contributors
|
|
||||||
==============
|
|
||||||
- georgemoralis
|
|
||||||
- raphaelthegreat
|
|
||||||
- skmp
|
|
||||||
- wheremyfoodat
|
|
||||||
|
|
||||||
4.Greetings
|
|
||||||
===========
|
|
||||||
I would like to thank the following people for helping me so far, with coding or moral support.
|
|
||||||
|
|
||||||
- wheremyfoodat - or @rodakinos for believed me
|
|
||||||
- paris - or OFFTKP for not believing me and that made me a better coder :D
|
|
||||||
- skmp - or kornilios for being good old friend
|
|
||||||
- PandaBad - our beloved stalker
|
|
||||||
- emufan4568 - for advices
|
|
||||||
- velocity - for talking 1-2 times per year on discord server. We miss you velocity
|
|
||||||
|
|
||||||
- probably more, will include in the next readme :D
|
|
|
@ -25,11 +25,6 @@ if (NOT TARGET fmt::fmt)
|
||||||
add_subdirectory(fmt)
|
add_subdirectory(fmt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Discord-RPC
|
|
||||||
set(BUILD_EXAMPLES OFF CACHE BOOL "")
|
|
||||||
add_subdirectory(discord-rpc)
|
|
||||||
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND MSVC)
|
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND MSVC)
|
||||||
# If it is clang and MSVC we will add a static lib
|
# If it is clang and MSVC we will add a static lib
|
||||||
# CryptoPP
|
# CryptoPP
|
||||||
|
@ -147,12 +142,18 @@ if (WIN32)
|
||||||
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
target_compile_options(sirit PUBLIC "-Wno-error=unused-command-line-argument")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
# half
|
||||||
|
add_library(half INTERFACE)
|
||||||
|
target_include_directories(half INTERFACE half/include)
|
||||||
|
|
||||||
# date
|
# date
|
||||||
if (APPLE AND NOT TARGET date::date-tz)
|
if (NOT TARGET date::date-tz)
|
||||||
option(BUILD_TZ_LIB "" ON)
|
option(BUILD_TZ_LIB "" ON)
|
||||||
option(USE_SYSTEM_TZ_DB "" ON)
|
option(USE_SYSTEM_TZ_DB "" ON)
|
||||||
add_subdirectory(date)
|
add_subdirectory(date)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Tracy
|
# Tracy
|
||||||
option(TRACY_ENABLE "" ON)
|
option(TRACY_ENABLE "" ON)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 4ec218155d73bcb8022f8f7ca72305d801f84beb
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7c4d91e7819a1d27213aa3499953d54ae1a00e8f
|
Subproject commit 12cbda959b6df2af119a76a73ff906c2bed36884
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1ddada225144cac0de8f6b5c0dd9acffd99a2e68
|
|
@ -1 +1 @@
|
||||||
Subproject commit 1115dad3ffa0994e3f43b693d9b9cc99944c64c1
|
Subproject commit 2c48a1a50203bbaf1e3d0d64c5d726d56f8d3bb3
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8db09231c448b913ae905d5237ce2eca46e3fe87
|
Subproject commit 37090c74cc6e680f2bc334cac8fd182f7634a1f6
|
|
@ -1 +1 @@
|
||||||
Subproject commit fcb1d3d7e5885edfadbbe9572991dc4b3248af58
|
Subproject commit 4b740127230472779c4a4d71e1a75aaa3a367a2d
|
|
@ -1 +1 @@
|
||||||
Subproject commit 871913da6a4b132b567d7b65c509600363c0041e
|
Subproject commit e1bdbca9baf4d682fb6066b380f4aa4a7bdbb58a
|
|
@ -1 +1 @@
|
||||||
Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd
|
Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9
|
|
@ -1 +1 @@
|
||||||
Subproject commit aabb091ae37068498751fd58202a9854408ecb0e
|
Subproject commit ccdf68421bc8eb85693f573080fc0a5faad862db
|
|
@ -1 +1 @@
|
||||||
Subproject commit ee65ff988bab34a184c700e2fbe1e1c5bc27485d
|
Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d
|
|
@ -1 +1 @@
|
||||||
Subproject commit 16c6a369c193981e9cf314126589eaa8763f92c3
|
Subproject commit bd73bc03b0aacaa89c9c203b9b43cd08f1b1843b
|
|
@ -114108,7 +114108,7 @@ STUB(
|
||||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
|
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
|
||||||
STUB("efPahl2FufA",
|
STUB("efPahl2FufA",
|
||||||
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
|
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
|
||||||
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlemetId)
|
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlementId)
|
||||||
STUB("efXnxYFN5oE", _ZNSt11range_errorD0Ev)
|
STUB("efXnxYFN5oE", _ZNSt11range_errorD0Ev)
|
||||||
STUB("efcwuDLsAM0", _ZThn120_NK7WebCore16HTMLMediaElement5mutedEv)
|
STUB("efcwuDLsAM0", _ZThn120_NK7WebCore16HTMLMediaElement5mutedEv)
|
||||||
STUB("efhGArzWdxE", _ZN7bmalloc6IsoTLS15s_didInitializeE)
|
STUB("efhGArzWdxE", _ZN7bmalloc6IsoTLS15s_didInitializeE)
|
||||||
|
@ -129493,7 +129493,7 @@ STUB(
|
||||||
STUB("kJlYH5uMAWI", sceNetResolverDestroy)
|
STUB("kJlYH5uMAWI", sceNetResolverDestroy)
|
||||||
STUB("kJmdxo4uM+8",
|
STUB("kJmdxo4uM+8",
|
||||||
_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE5_InitERKSt8_Locinfo)
|
_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE5_InitERKSt8_Locinfo)
|
||||||
STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlemetId)
|
STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlementId)
|
||||||
STUB(
|
STUB(
|
||||||
"kJoY9lMIFzY",
|
"kJoY9lMIFzY",
|
||||||
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)
|
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)
|
||||||
|
|
|
@ -80897,10 +80897,10 @@ sceAppCheckerExecute
|
||||||
sceAppCheckerExecuteEx
|
sceAppCheckerExecuteEx
|
||||||
sceAppContentAddcontDelete
|
sceAppContentAddcontDelete
|
||||||
sceAppContentAddcontEnqueueDownload
|
sceAppContentAddcontEnqueueDownload
|
||||||
sceAppContentAddcontEnqueueDownloadByEntitlemetId
|
sceAppContentAddcontEnqueueDownloadByEntitlementId
|
||||||
sceAppContentAddcontEnqueueDownloadSp
|
sceAppContentAddcontEnqueueDownloadSp
|
||||||
sceAppContentAddcontMount
|
sceAppContentAddcontMount
|
||||||
sceAppContentAddcontMountByEntitlemetId
|
sceAppContentAddcontMountByEntitlementId
|
||||||
sceAppContentAddcontShrink
|
sceAppContentAddcontShrink
|
||||||
sceAppContentAddcontUnmount
|
sceAppContentAddcontUnmount
|
||||||
sceAppContentAppParamGetInt
|
sceAppContentAppParamGetInt
|
||||||
|
|
|
@ -22,15 +22,15 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct PortOut {
|
struct PortOut {
|
||||||
bool isOpen = false;
|
SDL_AudioStream* stream = nullptr;
|
||||||
int type = 0;
|
|
||||||
u32 samples_num = 0;
|
u32 samples_num = 0;
|
||||||
u8 sample_size = 0;
|
|
||||||
u32 freq = 0;
|
u32 freq = 0;
|
||||||
u32 format = -1;
|
u32 format = -1;
|
||||||
|
int type = 0;
|
||||||
int channels_num = 0;
|
int channels_num = 0;
|
||||||
int volume[8] = {};
|
int volume[8] = {};
|
||||||
SDL_AudioStream* stream = nullptr;
|
u8 sample_size = 0;
|
||||||
|
bool isOpen = false;
|
||||||
};
|
};
|
||||||
std::shared_mutex m_mutex;
|
std::shared_mutex m_mutex;
|
||||||
std::array<PortOut, 22> portsOut; // main up to 8 ports , BGM 1 port , voice up to 4 ports ,
|
std::array<PortOut, 22> portsOut; // main up to 8 ports , BGM 1 port , voice up to 4 ports ,
|
||||||
|
|
|
@ -17,10 +17,12 @@ static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto
|
||||||
static std::string logFilter;
|
static std::string logFilter;
|
||||||
static std::string logType = "async";
|
static std::string logType = "async";
|
||||||
static std::string userName = "shadPS4";
|
static std::string userName = "shadPS4";
|
||||||
|
static bool useSpecialPad = false;
|
||||||
|
static int specialPadClass = 1;
|
||||||
static bool isDebugDump = false;
|
static bool isDebugDump = false;
|
||||||
static bool isLibc = true;
|
|
||||||
static bool isShowSplash = false;
|
static bool isShowSplash = false;
|
||||||
static bool isNullGpu = false;
|
static bool isNullGpu = false;
|
||||||
|
static bool shouldCopyGPUBuffers = false;
|
||||||
static bool shouldDumpShaders = false;
|
static bool shouldDumpShaders = false;
|
||||||
static bool shouldDumpPM4 = false;
|
static bool shouldDumpPM4 = false;
|
||||||
static u32 vblankDivider = 1;
|
static u32 vblankDivider = 1;
|
||||||
|
@ -46,13 +48,10 @@ u32 m_window_size_H = 720;
|
||||||
std::vector<std::string> m_pkg_viewer;
|
std::vector<std::string> m_pkg_viewer;
|
||||||
std::vector<std::string> m_elf_viewer;
|
std::vector<std::string> m_elf_viewer;
|
||||||
std::vector<std::string> m_recent_files;
|
std::vector<std::string> m_recent_files;
|
||||||
|
std::string emulator_language = "en";
|
||||||
// Settings
|
// Settings
|
||||||
u32 m_language = 1; // english
|
u32 m_language = 1; // english
|
||||||
|
|
||||||
bool isLleLibc() {
|
|
||||||
return isLibc;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNeoMode() {
|
bool isNeoMode() {
|
||||||
return isNeo;
|
return isNeo;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +84,14 @@ std::string getUserName() {
|
||||||
return userName;
|
return userName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getUseSpecialPad() {
|
||||||
|
return useSpecialPad;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSpecialPadClass() {
|
||||||
|
return specialPadClass;
|
||||||
|
}
|
||||||
|
|
||||||
bool debugDump() {
|
bool debugDump() {
|
||||||
return isDebugDump;
|
return isDebugDump;
|
||||||
}
|
}
|
||||||
|
@ -97,6 +104,10 @@ bool nullGpu() {
|
||||||
return isNullGpu;
|
return isNullGpu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool copyGPUCmdBuffers() {
|
||||||
|
return shouldCopyGPUBuffers;
|
||||||
|
}
|
||||||
|
|
||||||
bool dumpShaders() {
|
bool dumpShaders() {
|
||||||
return shouldDumpShaders;
|
return shouldDumpShaders;
|
||||||
}
|
}
|
||||||
|
@ -153,6 +164,10 @@ void setNullGpu(bool enable) {
|
||||||
isNullGpu = enable;
|
isNullGpu = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setCopyGPUCmdBuffers(bool enable) {
|
||||||
|
shouldCopyGPUBuffers = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void setDumpShaders(bool enable) {
|
void setDumpShaders(bool enable) {
|
||||||
shouldDumpShaders = enable;
|
shouldDumpShaders = enable;
|
||||||
}
|
}
|
||||||
|
@ -189,18 +204,26 @@ void setNeoMode(bool enable) {
|
||||||
isNeo = enable;
|
isNeo = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLogType(std::string type) {
|
void setLogType(const std::string& type) {
|
||||||
logType = type;
|
logType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLogFilter(std::string type) {
|
void setLogFilter(const std::string& type) {
|
||||||
logFilter = type;
|
logFilter = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setUserName(std::string type) {
|
void setUserName(const std::string& type) {
|
||||||
userName = type;
|
userName = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setUseSpecialPad(bool use) {
|
||||||
|
useSpecialPad = use;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSpecialPadClass(int type) {
|
||||||
|
specialPadClass = type;
|
||||||
|
}
|
||||||
|
|
||||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
||||||
main_window_geometry_x = x;
|
main_window_geometry_x = x;
|
||||||
main_window_geometry_y = y;
|
main_window_geometry_y = y;
|
||||||
|
@ -219,10 +242,10 @@ void setIconSize(u32 size) {
|
||||||
void setIconSizeGrid(u32 size) {
|
void setIconSizeGrid(u32 size) {
|
||||||
m_icon_size_grid = size;
|
m_icon_size_grid = size;
|
||||||
}
|
}
|
||||||
void setSliderPositon(u32 pos) {
|
void setSliderPosition(u32 pos) {
|
||||||
m_slider_pos = pos;
|
m_slider_pos = pos;
|
||||||
}
|
}
|
||||||
void setSliderPositonGrid(u32 pos) {
|
void setSliderPositionGrid(u32 pos) {
|
||||||
m_slider_pos_grid = pos;
|
m_slider_pos_grid = pos;
|
||||||
}
|
}
|
||||||
void setTableMode(u32 mode) {
|
void setTableMode(u32 mode) {
|
||||||
|
@ -234,19 +257,23 @@ void setMainWindowWidth(u32 width) {
|
||||||
void setMainWindowHeight(u32 height) {
|
void setMainWindowHeight(u32 height) {
|
||||||
m_window_size_H = height;
|
m_window_size_H = height;
|
||||||
}
|
}
|
||||||
void setPkgViewer(std::vector<std::string> pkgList) {
|
void setPkgViewer(const std::vector<std::string>& pkgList) {
|
||||||
m_pkg_viewer.resize(pkgList.size());
|
m_pkg_viewer.resize(pkgList.size());
|
||||||
m_pkg_viewer = pkgList;
|
m_pkg_viewer = pkgList;
|
||||||
}
|
}
|
||||||
void setElfViewer(std::vector<std::string> elfList) {
|
void setElfViewer(const std::vector<std::string>& elfList) {
|
||||||
m_elf_viewer.resize(elfList.size());
|
m_elf_viewer.resize(elfList.size());
|
||||||
m_elf_viewer = elfList;
|
m_elf_viewer = elfList;
|
||||||
}
|
}
|
||||||
void setRecentFiles(std::vector<std::string> recentFiles) {
|
void setRecentFiles(const std::vector<std::string>& recentFiles) {
|
||||||
m_recent_files.resize(recentFiles.size());
|
m_recent_files.resize(recentFiles.size());
|
||||||
m_recent_files = recentFiles;
|
m_recent_files = recentFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setEmulatorLanguage(std::string language) {
|
||||||
|
emulator_language = language;
|
||||||
|
}
|
||||||
|
|
||||||
u32 getMainWindowGeometryX() {
|
u32 getMainWindowGeometryX() {
|
||||||
return main_window_geometry_x;
|
return main_window_geometry_x;
|
||||||
}
|
}
|
||||||
|
@ -271,10 +298,10 @@ u32 getIconSize() {
|
||||||
u32 getIconSizeGrid() {
|
u32 getIconSizeGrid() {
|
||||||
return m_icon_size_grid;
|
return m_icon_size_grid;
|
||||||
}
|
}
|
||||||
u32 getSliderPositon() {
|
u32 getSliderPosition() {
|
||||||
return m_slider_pos;
|
return m_slider_pos;
|
||||||
}
|
}
|
||||||
u32 getSliderPositonGrid() {
|
u32 getSliderPositionGrid() {
|
||||||
return m_slider_pos_grid;
|
return m_slider_pos_grid;
|
||||||
}
|
}
|
||||||
u32 getTableMode() {
|
u32 getTableMode() {
|
||||||
|
@ -296,6 +323,10 @@ std::vector<std::string> getRecentFiles() {
|
||||||
return m_recent_files;
|
return m_recent_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string getEmulatorLanguage() {
|
||||||
|
return emulator_language;
|
||||||
|
}
|
||||||
|
|
||||||
u32 GetLanguage() {
|
u32 GetLanguage() {
|
||||||
return m_language;
|
return m_language;
|
||||||
}
|
}
|
||||||
|
@ -326,12 +357,20 @@ void load(const std::filesystem::path& path) {
|
||||||
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (data.contains("Input")) {
|
||||||
|
const toml::value& input = data.at("Input");
|
||||||
|
|
||||||
|
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
||||||
|
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (data.contains("GPU")) {
|
if (data.contains("GPU")) {
|
||||||
const toml::value& gpu = data.at("GPU");
|
const toml::value& gpu = data.at("GPU");
|
||||||
|
|
||||||
screenWidth = toml::find_or<int>(gpu, "screenWidth", screenWidth);
|
screenWidth = toml::find_or<int>(gpu, "screenWidth", screenWidth);
|
||||||
screenHeight = toml::find_or<int>(gpu, "screenHeight", screenHeight);
|
screenHeight = toml::find_or<int>(gpu, "screenHeight", screenHeight);
|
||||||
isNullGpu = toml::find_or<bool>(gpu, "nullGpu", false);
|
isNullGpu = toml::find_or<bool>(gpu, "nullGpu", false);
|
||||||
|
shouldCopyGPUBuffers = toml::find_or<bool>(gpu, "copyGPUBuffers", false);
|
||||||
shouldDumpShaders = toml::find_or<bool>(gpu, "dumpShaders", false);
|
shouldDumpShaders = toml::find_or<bool>(gpu, "dumpShaders", false);
|
||||||
shouldDumpPM4 = toml::find_or<bool>(gpu, "dumpPM4", false);
|
shouldDumpPM4 = toml::find_or<bool>(gpu, "dumpPM4", false);
|
||||||
vblankDivider = toml::find_or<int>(gpu, "vblankDivider", 1);
|
vblankDivider = toml::find_or<int>(gpu, "vblankDivider", 1);
|
||||||
|
@ -354,12 +393,6 @@ void load(const std::filesystem::path& path) {
|
||||||
isDebugDump = toml::find_or<bool>(debug, "DebugDump", false);
|
isDebugDump = toml::find_or<bool>(debug, "DebugDump", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.contains("LLE")) {
|
|
||||||
const toml::value& lle = data.at("LLE");
|
|
||||||
|
|
||||||
isLibc = toml::find_or<bool>(lle, "libc", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.contains("GUI")) {
|
if (data.contains("GUI")) {
|
||||||
const toml::value& gui = data.at("GUI");
|
const toml::value& gui = data.at("GUI");
|
||||||
|
|
||||||
|
@ -379,6 +412,7 @@ void load(const std::filesystem::path& path) {
|
||||||
m_elf_viewer = toml::find_or<std::vector<std::string>>(gui, "elfDirs", {});
|
m_elf_viewer = toml::find_or<std::vector<std::string>>(gui, "elfDirs", {});
|
||||||
m_recent_files = toml::find_or<std::vector<std::string>>(gui, "recentFiles", {});
|
m_recent_files = toml::find_or<std::vector<std::string>>(gui, "recentFiles", {});
|
||||||
m_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
m_table_mode = toml::find_or<int>(gui, "gameTableMode", 0);
|
||||||
|
emulator_language = toml::find_or<std::string>(gui, "emulatorLanguage", "en");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.contains("Settings")) {
|
if (data.contains("Settings")) {
|
||||||
|
@ -412,9 +446,12 @@ void save(const std::filesystem::path& path) {
|
||||||
data["General"]["logType"] = logType;
|
data["General"]["logType"] = logType;
|
||||||
data["General"]["userName"] = userName;
|
data["General"]["userName"] = userName;
|
||||||
data["General"]["showSplash"] = isShowSplash;
|
data["General"]["showSplash"] = isShowSplash;
|
||||||
|
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||||
|
data["Input"]["specialPadClass"] = specialPadClass;
|
||||||
data["GPU"]["screenWidth"] = screenWidth;
|
data["GPU"]["screenWidth"] = screenWidth;
|
||||||
data["GPU"]["screenHeight"] = screenHeight;
|
data["GPU"]["screenHeight"] = screenHeight;
|
||||||
data["GPU"]["nullGpu"] = isNullGpu;
|
data["GPU"]["nullGpu"] = isNullGpu;
|
||||||
|
data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers;
|
||||||
data["GPU"]["dumpShaders"] = shouldDumpShaders;
|
data["GPU"]["dumpShaders"] = shouldDumpShaders;
|
||||||
data["GPU"]["dumpPM4"] = shouldDumpPM4;
|
data["GPU"]["dumpPM4"] = shouldDumpPM4;
|
||||||
data["GPU"]["vblankDivider"] = vblankDivider;
|
data["GPU"]["vblankDivider"] = vblankDivider;
|
||||||
|
@ -425,7 +462,6 @@ void save(const std::filesystem::path& path) {
|
||||||
data["Vulkan"]["rdocEnable"] = rdocEnable;
|
data["Vulkan"]["rdocEnable"] = rdocEnable;
|
||||||
data["Vulkan"]["rdocMarkersEnable"] = rdocMarkersEnable;
|
data["Vulkan"]["rdocMarkersEnable"] = rdocMarkersEnable;
|
||||||
data["Debug"]["DebugDump"] = isDebugDump;
|
data["Debug"]["DebugDump"] = isDebugDump;
|
||||||
data["LLE"]["libc"] = isLibc;
|
|
||||||
data["GUI"]["theme"] = mw_themes;
|
data["GUI"]["theme"] = mw_themes;
|
||||||
data["GUI"]["iconSize"] = m_icon_size;
|
data["GUI"]["iconSize"] = m_icon_size;
|
||||||
data["GUI"]["sliderPos"] = m_slider_pos;
|
data["GUI"]["sliderPos"] = m_slider_pos;
|
||||||
|
@ -442,6 +478,7 @@ void save(const std::filesystem::path& path) {
|
||||||
data["GUI"]["pkgDirs"] = m_pkg_viewer;
|
data["GUI"]["pkgDirs"] = m_pkg_viewer;
|
||||||
data["GUI"]["elfDirs"] = m_elf_viewer;
|
data["GUI"]["elfDirs"] = m_elf_viewer;
|
||||||
data["GUI"]["recentFiles"] = m_recent_files;
|
data["GUI"]["recentFiles"] = m_recent_files;
|
||||||
|
data["GUI"]["emulatorLanguage"] = emulator_language;
|
||||||
|
|
||||||
data["Settings"]["consoleLanguage"] = m_language;
|
data["Settings"]["consoleLanguage"] = m_language;
|
||||||
|
|
||||||
|
@ -458,6 +495,8 @@ void setDefaultValues() {
|
||||||
logFilter = "";
|
logFilter = "";
|
||||||
logType = "async";
|
logType = "async";
|
||||||
userName = "shadPS4";
|
userName = "shadPS4";
|
||||||
|
useSpecialPad = false;
|
||||||
|
specialPadClass = 1;
|
||||||
isDebugDump = false;
|
isDebugDump = false;
|
||||||
isShowSplash = false;
|
isShowSplash = false;
|
||||||
isNullGpu = false;
|
isNullGpu = false;
|
||||||
|
@ -466,6 +505,7 @@ void setDefaultValues() {
|
||||||
vblankDivider = 1;
|
vblankDivider = 1;
|
||||||
vkValidation = false;
|
vkValidation = false;
|
||||||
rdocEnable = false;
|
rdocEnable = false;
|
||||||
|
emulator_language = "en";
|
||||||
m_language = 1;
|
m_language = 1;
|
||||||
gpuId = -1;
|
gpuId = -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,14 +17,17 @@ std::string getLogFilter();
|
||||||
std::string getLogType();
|
std::string getLogType();
|
||||||
std::string getUserName();
|
std::string getUserName();
|
||||||
|
|
||||||
|
bool getUseSpecialPad();
|
||||||
|
int getSpecialPadClass();
|
||||||
|
|
||||||
u32 getScreenWidth();
|
u32 getScreenWidth();
|
||||||
u32 getScreenHeight();
|
u32 getScreenHeight();
|
||||||
s32 getGpuId();
|
s32 getGpuId();
|
||||||
|
|
||||||
bool debugDump();
|
bool debugDump();
|
||||||
bool isLleLibc();
|
|
||||||
bool showSplash();
|
bool showSplash();
|
||||||
bool nullGpu();
|
bool nullGpu();
|
||||||
|
bool copyGPUCmdBuffers();
|
||||||
bool dumpShaders();
|
bool dumpShaders();
|
||||||
bool dumpPM4();
|
bool dumpPM4();
|
||||||
bool isRdocEnabled();
|
bool isRdocEnabled();
|
||||||
|
@ -34,6 +37,7 @@ u32 vblankDiv();
|
||||||
void setDebugDump(bool enable);
|
void setDebugDump(bool enable);
|
||||||
void setShowSplash(bool enable);
|
void setShowSplash(bool enable);
|
||||||
void setNullGpu(bool enable);
|
void setNullGpu(bool enable);
|
||||||
|
void setCopyGPUCmdBuffers(bool enable);
|
||||||
void setDumpShaders(bool enable);
|
void setDumpShaders(bool enable);
|
||||||
void setDumpPM4(bool enable);
|
void setDumpPM4(bool enable);
|
||||||
void setVblankDiv(u32 value);
|
void setVblankDiv(u32 value);
|
||||||
|
@ -43,10 +47,13 @@ void setScreenHeight(u32 height);
|
||||||
void setFullscreenMode(bool enable);
|
void setFullscreenMode(bool enable);
|
||||||
void setLanguage(u32 language);
|
void setLanguage(u32 language);
|
||||||
void setNeoMode(bool enable);
|
void setNeoMode(bool enable);
|
||||||
void setUserName(std::string type);
|
void setUserName(const std::string& type);
|
||||||
|
|
||||||
void setLogType(std::string type);
|
void setUseSpecialPad(bool use);
|
||||||
void setLogFilter(std::string type);
|
void setSpecialPadClass(int type);
|
||||||
|
|
||||||
|
void setLogType(const std::string& type);
|
||||||
|
void setLogFilter(const std::string& type);
|
||||||
|
|
||||||
void setVkValidation(bool enable);
|
void setVkValidation(bool enable);
|
||||||
void setVkSyncValidation(bool enable);
|
void setVkSyncValidation(bool enable);
|
||||||
|
@ -62,14 +69,15 @@ void setGameInstallDir(const std::string& dir);
|
||||||
void setMainWindowTheme(u32 theme);
|
void setMainWindowTheme(u32 theme);
|
||||||
void setIconSize(u32 size);
|
void setIconSize(u32 size);
|
||||||
void setIconSizeGrid(u32 size);
|
void setIconSizeGrid(u32 size);
|
||||||
void setSliderPositon(u32 pos);
|
void setSliderPosition(u32 pos);
|
||||||
void setSliderPositonGrid(u32 pos);
|
void setSliderPositionGrid(u32 pos);
|
||||||
void setTableMode(u32 mode);
|
void setTableMode(u32 mode);
|
||||||
void setMainWindowWidth(u32 width);
|
void setMainWindowWidth(u32 width);
|
||||||
void setMainWindowHeight(u32 height);
|
void setMainWindowHeight(u32 height);
|
||||||
void setPkgViewer(std::vector<std::string> pkgList);
|
void setPkgViewer(const std::vector<std::string>& pkgList);
|
||||||
void setElfViewer(std::vector<std::string> elfList);
|
void setElfViewer(const std::vector<std::string>& elfList);
|
||||||
void setRecentFiles(std::vector<std::string> recentFiles);
|
void setRecentFiles(const std::vector<std::string>& recentFiles);
|
||||||
|
void setEmulatorLanguage(std::string language);
|
||||||
|
|
||||||
u32 getMainWindowGeometryX();
|
u32 getMainWindowGeometryX();
|
||||||
u32 getMainWindowGeometryY();
|
u32 getMainWindowGeometryY();
|
||||||
|
@ -79,14 +87,15 @@ std::string getGameInstallDir();
|
||||||
u32 getMainWindowTheme();
|
u32 getMainWindowTheme();
|
||||||
u32 getIconSize();
|
u32 getIconSize();
|
||||||
u32 getIconSizeGrid();
|
u32 getIconSizeGrid();
|
||||||
u32 getSliderPositon();
|
u32 getSliderPosition();
|
||||||
u32 getSliderPositonGrid();
|
u32 getSliderPositionGrid();
|
||||||
u32 getTableMode();
|
u32 getTableMode();
|
||||||
u32 getMainWindowWidth();
|
u32 getMainWindowWidth();
|
||||||
u32 getMainWindowHeight();
|
u32 getMainWindowHeight();
|
||||||
std::vector<std::string> getPkgViewer();
|
std::vector<std::string> getPkgViewer();
|
||||||
std::vector<std::string> getElfViewer();
|
std::vector<std::string> getElfViewer();
|
||||||
std::vector<std::string> getRecentFiles();
|
std::vector<std::string> getRecentFiles();
|
||||||
|
std::string getEmulatorLanguage();
|
||||||
|
|
||||||
void setDefaultValues();
|
void setDefaultValues();
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ static inline bool IsProfilerConnected() {
|
||||||
#define TRACK_ALLOC(ptr, size, pool) TracyAllocN(std::bit_cast<void*>(ptr), (size), (pool))
|
#define TRACK_ALLOC(ptr, size, pool) TracyAllocN(std::bit_cast<void*>(ptr), (size), (pool))
|
||||||
#define TRACK_FREE(ptr, pool) TracyFreeN(std::bit_cast<void*>(ptr), (pool))
|
#define TRACK_FREE(ptr, pool) TracyFreeN(std::bit_cast<void*>(ptr), (pool))
|
||||||
|
|
||||||
enum MarkersPallete : int {
|
enum MarkersPalette : int {
|
||||||
EmulatorMarkerColor = 0x264653,
|
EmulatorMarkerColor = 0x264653,
|
||||||
RendererMarkerColor = 0x2a9d8f,
|
RendererMarkerColor = 0x2a9d8f,
|
||||||
HleMarkerColor = 0xe9c46a,
|
HleMarkerColor = 0xe9c46a,
|
||||||
|
|
|
@ -217,7 +217,7 @@ void IOFile::Close() {
|
||||||
file = nullptr;
|
file = nullptr;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
if (file_mapping) {
|
if (file_mapping && file_access_mode == FileAccessMode::ReadWrite) {
|
||||||
CloseHandle(std::bit_cast<HANDLE>(file_mapping));
|
CloseHandle(std::bit_cast<HANDLE>(file_mapping));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -259,8 +259,7 @@ uintptr_t IOFile::GetFileMapping() {
|
||||||
mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_WRITE, PAGE_READWRITE, SEC_COMMIT, 0,
|
mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_WRITE, PAGE_READWRITE, SEC_COMMIT, 0,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_READ, PAGE_READONLY, SEC_COMMIT, 0, NULL,
|
mapping = hfile;
|
||||||
NULL, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
file_mapping = std::bit_cast<uintptr_t>(mapping);
|
file_mapping = std::bit_cast<uintptr_t>(mapping);
|
||||||
|
|
|
@ -112,6 +112,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||||
SUB(Lib, ErrorDialog) \
|
SUB(Lib, ErrorDialog) \
|
||||||
SUB(Lib, ImeDialog) \
|
SUB(Lib, ImeDialog) \
|
||||||
SUB(Lib, AvPlayer) \
|
SUB(Lib, AvPlayer) \
|
||||||
|
SUB(Lib, Ngs2) \
|
||||||
CLS(Frontend) \
|
CLS(Frontend) \
|
||||||
CLS(Render) \
|
CLS(Render) \
|
||||||
SUB(Render, Vulkan) \
|
SUB(Render, Vulkan) \
|
||||||
|
|
|
@ -79,6 +79,7 @@ enum class Class : u8 {
|
||||||
Lib_ErrorDialog, ///< The LibSceErrorDialog implementation.
|
Lib_ErrorDialog, ///< The LibSceErrorDialog implementation.
|
||||||
Lib_ImeDialog, ///< The LibSceImeDialog implementation.
|
Lib_ImeDialog, ///< The LibSceImeDialog implementation.
|
||||||
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
Lib_AvPlayer, ///< The LibSceAvPlayer implementation.
|
||||||
|
Lib_Ngs2, ///< The LibSceNgs2 implementation.
|
||||||
Frontend, ///< Emulator UI
|
Frontend, ///< Emulator UI
|
||||||
Render, ///< Video Core
|
Render, ///< Video Core
|
||||||
Render_Vulkan, ///< Vulkan backend
|
Render_Vulkan, ///< Vulkan backend
|
||||||
|
|
|
@ -18,16 +18,16 @@ NativeClock::NativeClock()
|
||||||
us_rdtsc_factor{GetFixedPoint64Factor(std::micro::den, rdtsc_frequency)},
|
us_rdtsc_factor{GetFixedPoint64Factor(std::micro::den, rdtsc_frequency)},
|
||||||
ms_rdtsc_factor{GetFixedPoint64Factor(std::milli::den, rdtsc_frequency)} {}
|
ms_rdtsc_factor{GetFixedPoint64Factor(std::milli::den, rdtsc_frequency)} {}
|
||||||
|
|
||||||
u64 NativeClock::GetTimeNS() const {
|
u64 NativeClock::GetTimeNS(u64 base_ptc /*= 0*/) const {
|
||||||
return MultiplyHigh(GetUptime(), ns_rdtsc_factor);
|
return MultiplyHigh(GetUptime() - base_ptc, ns_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetTimeUS() const {
|
u64 NativeClock::GetTimeUS(u64 base_ptc /*= 0*/) const {
|
||||||
return MultiplyHigh(GetUptime(), us_rdtsc_factor);
|
return MultiplyHigh(GetUptime() - base_ptc, us_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetTimeMS() const {
|
u64 NativeClock::GetTimeMS(u64 base_ptc /*= 0*/) const {
|
||||||
return MultiplyHigh(GetUptime(), ms_rdtsc_factor);
|
return MultiplyHigh(GetUptime() - base_ptc, ms_rdtsc_factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 NativeClock::GetUptime() const {
|
u64 NativeClock::GetUptime() const {
|
||||||
|
|
|
@ -16,9 +16,9 @@ public:
|
||||||
return rdtsc_frequency;
|
return rdtsc_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 GetTimeNS() const;
|
u64 GetTimeNS(u64 base_ptc = 0) const;
|
||||||
u64 GetTimeUS() const;
|
u64 GetTimeUS(u64 base_ptc = 0) const;
|
||||||
u64 GetTimeMS() const;
|
u64 GetTimeMS(u64 base_ptc = 0) const;
|
||||||
u64 GetUptime() const;
|
u64 GetUptime() const;
|
||||||
u64 GetProcessTimeUS() const;
|
u64 GetProcessTimeUS() const;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <CoreFoundation/CFBundle.h>
|
#include <CoreFoundation/CFBundle.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,26 +27,55 @@ namespace Common::FS {
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
using IsTranslocatedURLFunc = Boolean (*)(CFURLRef path, bool* isTranslocated,
|
||||||
|
CFErrorRef* __nullable error);
|
||||||
|
using CreateOriginalPathForURLFunc = CFURLRef __nullable (*)(CFURLRef translocatedPath,
|
||||||
|
CFErrorRef* __nullable error);
|
||||||
|
|
||||||
|
static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) {
|
||||||
|
if (void* security_handle =
|
||||||
|
dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY)) {
|
||||||
|
SCOPE_EXIT {
|
||||||
|
dlclose(security_handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto IsTranslocatedURL = reinterpret_cast<IsTranslocatedURLFunc>(
|
||||||
|
dlsym(security_handle, "SecTranslocateIsTranslocatedURL"));
|
||||||
|
const auto CreateOriginalPathForURL = reinterpret_cast<CreateOriginalPathForURLFunc>(
|
||||||
|
dlsym(security_handle, "SecTranslocateCreateOriginalPathForURL"));
|
||||||
|
|
||||||
|
bool is_translocated = false;
|
||||||
|
if (IsTranslocatedURL && CreateOriginalPathForURL &&
|
||||||
|
IsTranslocatedURL(bundle_path, &is_translocated, nullptr) && is_translocated) {
|
||||||
|
return CreateOriginalPathForURL(bundle_path, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static std::filesystem::path GetBundleParentDirectory() {
|
static std::filesystem::path GetBundleParentDirectory() {
|
||||||
if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) {
|
if (CFBundleRef bundle_ref = CFBundleGetMainBundle()) {
|
||||||
if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) {
|
if (CFURLRef bundle_url_ref = CFBundleCopyBundleURL(bundle_ref)) {
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
CFRelease(bundle_url_ref);
|
CFRelease(bundle_url_ref);
|
||||||
};
|
};
|
||||||
if (CFStringRef bundle_path_ref =
|
|
||||||
CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle)) {
|
CFURLRef untranslocated_url_ref = UntranslocateBundlePath(bundle_url_ref);
|
||||||
SCOPE_EXIT {
|
SCOPE_EXIT {
|
||||||
CFRelease(bundle_path_ref);
|
if (untranslocated_url_ref) {
|
||||||
|
CFRelease(untranslocated_url_ref);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
char app_bundle_path[MAXPATHLEN];
|
char app_bundle_path[MAXPATHLEN];
|
||||||
if (CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path,
|
if (CFURLGetFileSystemRepresentation(
|
||||||
sizeof(app_bundle_path))) {
|
untranslocated_url_ref ? untranslocated_url_ref : bundle_url_ref, true,
|
||||||
|
reinterpret_cast<u8*>(app_bundle_path), sizeof(app_bundle_path))) {
|
||||||
std::filesystem::path bundle_path{app_bundle_path};
|
std::filesystem::path bundle_path{app_bundle_path};
|
||||||
return bundle_path.parent_path();
|
return bundle_path.parent_path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return std::filesystem::current_path();
|
return std::filesystem::current_path();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -74,6 +104,9 @@ static auto UserPaths = [] {
|
||||||
create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR);
|
create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR);
|
||||||
create_path(PathType::DownloadDir, user_dir / DOWNLOAD_DIR);
|
create_path(PathType::DownloadDir, user_dir / DOWNLOAD_DIR);
|
||||||
create_path(PathType::CapturesDir, user_dir / CAPTURES_DIR);
|
create_path(PathType::CapturesDir, user_dir / CAPTURES_DIR);
|
||||||
|
create_path(PathType::CheatsDir, user_dir / CHEATS_DIR);
|
||||||
|
create_path(PathType::PatchesDir, user_dir / PATCHES_DIR);
|
||||||
|
create_path(PathType::AddonsDir, user_dir / ADDONS_DIR);
|
||||||
|
|
||||||
return paths;
|
return paths;
|
||||||
}();
|
}();
|
||||||
|
|
|
@ -20,6 +20,9 @@ enum class PathType {
|
||||||
SysModuleDir, // Where system modules are stored.
|
SysModuleDir, // Where system modules are stored.
|
||||||
DownloadDir, // Where downloads/temp files are stored.
|
DownloadDir, // Where downloads/temp files are stored.
|
||||||
CapturesDir, // Where rdoc captures are stored.
|
CapturesDir, // Where rdoc captures are stored.
|
||||||
|
CheatsDir, // Where cheats are stored.
|
||||||
|
PatchesDir, // Where patches are stored.
|
||||||
|
AddonsDir, // Where additional content is stored.
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto PORTABLE_DIR = "user";
|
constexpr auto PORTABLE_DIR = "user";
|
||||||
|
@ -35,6 +38,9 @@ constexpr auto TEMPDATA_DIR = "temp";
|
||||||
constexpr auto SYSMODULES_DIR = "sys_modules";
|
constexpr auto SYSMODULES_DIR = "sys_modules";
|
||||||
constexpr auto DOWNLOAD_DIR = "download";
|
constexpr auto DOWNLOAD_DIR = "download";
|
||||||
constexpr auto CAPTURES_DIR = "captures";
|
constexpr auto CAPTURES_DIR = "captures";
|
||||||
|
constexpr auto CHEATS_DIR = "cheats";
|
||||||
|
constexpr auto PATCHES_DIR = "patches";
|
||||||
|
constexpr auto ADDONS_DIR = "addcont";
|
||||||
|
|
||||||
// Filenames
|
// Filenames
|
||||||
constexpr auto LOG_FILE = "shad_log.txt";
|
constexpr auto LOG_FILE = "shad_log.txt";
|
||||||
|
|
|
@ -28,9 +28,13 @@ struct SlotId {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class SlotVector {
|
class SlotVector {
|
||||||
constexpr static std::size_t InitialCapacity = 1024;
|
constexpr static std::size_t InitialCapacity = 2048;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
SlotVector() {
|
||||||
|
Reserve(InitialCapacity);
|
||||||
|
}
|
||||||
|
|
||||||
~SlotVector() noexcept {
|
~SlotVector() noexcept {
|
||||||
std::size_t index = 0;
|
std::size_t index = 0;
|
||||||
for (u64 bits : stored_bitset) {
|
for (u64 bits : stored_bitset) {
|
||||||
|
@ -67,19 +71,6 @@ public:
|
||||||
return SlotId{index};
|
return SlotId{index};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename... Args>
|
|
||||||
[[nodiscard]] SlotId swap_and_insert(SlotId existing_id, Args&&... args) noexcept {
|
|
||||||
const u32 index = FreeValueIndex();
|
|
||||||
T& existing_value = values[existing_id.index].object;
|
|
||||||
|
|
||||||
new (&values[index].object) T(std::move(existing_value));
|
|
||||||
existing_value.~T();
|
|
||||||
new (&values[existing_id.index].object) T(std::forward<Args>(args)...);
|
|
||||||
SetStorageBit(index);
|
|
||||||
|
|
||||||
return SlotId{index};
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase(SlotId id) noexcept {
|
void erase(SlotId id) noexcept {
|
||||||
values[id.index].object.~T();
|
values[id.index].object.~T();
|
||||||
free_list.push_back(id.index);
|
free_list.push_back(id.index);
|
||||||
|
@ -151,7 +142,8 @@ private:
|
||||||
|
|
||||||
const std::size_t old_free_size = free_list.size();
|
const std::size_t old_free_size = free_list.size();
|
||||||
free_list.resize(old_free_size + (new_capacity - values_capacity));
|
free_list.resize(old_free_size + (new_capacity - values_capacity));
|
||||||
std::iota(free_list.begin() + old_free_size, free_list.end(),
|
const std::size_t new_free_size = free_list.size();
|
||||||
|
std::iota(free_list.rbegin(), free_list.rbegin() + new_free_size - old_free_size,
|
||||||
static_cast<u32>(values_capacity));
|
static_cast<u32>(values_capacity));
|
||||||
|
|
||||||
delete[] values;
|
delete[] values;
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace Common {
|
||||||
|
|
||||||
// This function divides a u128 by a u32 value and produces two u64 values:
|
// This function divides a u128 by a u32 value and produces two u64 values:
|
||||||
// the result of division and the remainder
|
// the result of division and the remainder
|
||||||
[[nodiscard]] static inline std::pair<u64, u64> Divide128On32(u128 dividend, u32 divisor) {
|
[[nodiscard]] static inline std::pair<u64, u64> Divide128On32(const u128& dividend, u32 divisor) {
|
||||||
u64 remainder = dividend[0] % divisor;
|
u64 remainder = dividend[0] % divisor;
|
||||||
u64 accum = dividend[0] / divisor;
|
u64 accum = dividend[0] / divisor;
|
||||||
if (dividend[1] == 0)
|
if (dividend[1] == 0)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <boost/icl/separate_interval_set.hpp>
|
#include <boost/icl/separate_interval_set.hpp>
|
||||||
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "core/address_space.h"
|
#include "core/address_space.h"
|
||||||
|
@ -98,7 +99,7 @@ struct AddressSpace::Impl {
|
||||||
backing_handle =
|
backing_handle =
|
||||||
CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ,
|
CreateFileMapping2(INVALID_HANDLE_VALUE, nullptr, FILE_MAP_WRITE | FILE_MAP_READ,
|
||||||
PAGE_READWRITE, SEC_COMMIT, BackingSize, nullptr, nullptr, 0);
|
PAGE_READWRITE, SEC_COMMIT, BackingSize, nullptr, nullptr, 0);
|
||||||
ASSERT(backing_handle);
|
ASSERT_MSG(backing_handle, "{}", Common::GetLastErrorMsg());
|
||||||
// Allocate a virtual memory for the backing file map as placeholder
|
// Allocate a virtual memory for the backing file map as placeholder
|
||||||
backing_base = static_cast<u8*>(VirtualAlloc2(process, nullptr, BackingSize,
|
backing_base = static_cast<u8*>(VirtualAlloc2(process, nullptr, BackingSize,
|
||||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||||
|
@ -106,7 +107,7 @@ struct AddressSpace::Impl {
|
||||||
// Map backing placeholder. This will commit the pages
|
// Map backing placeholder. This will commit the pages
|
||||||
void* const ret = MapViewOfFile3(backing_handle, process, backing_base, 0, BackingSize,
|
void* const ret = MapViewOfFile3(backing_handle, process, backing_base, 0, BackingSize,
|
||||||
MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
|
MEM_REPLACE_PLACEHOLDER, PAGE_READWRITE, nullptr, 0);
|
||||||
ASSERT(ret == backing_base);
|
ASSERT_MSG(ret == backing_base, "{}", Common::GetLastErrorMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
~Impl() {
|
~Impl() {
|
||||||
|
@ -129,9 +130,10 @@ struct AddressSpace::Impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, ULONG prot, uintptr_t fd = 0) {
|
void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, ULONG prot, uintptr_t fd = 0) {
|
||||||
|
const size_t aligned_size = Common::AlignUp(size, 16_KB);
|
||||||
const auto it = placeholders.find(virtual_addr);
|
const auto it = placeholders.find(virtual_addr);
|
||||||
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
||||||
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + size <= it->upper(),
|
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + aligned_size <= it->upper(),
|
||||||
"Map range must be fully contained in a placeholder");
|
"Map range must be fully contained in a placeholder");
|
||||||
|
|
||||||
// Windows only allows splitting a placeholder into two.
|
// Windows only allows splitting a placeholder into two.
|
||||||
|
@ -140,7 +142,7 @@ struct AddressSpace::Impl {
|
||||||
// one at the start and at the end.
|
// one at the start and at the end.
|
||||||
const VAddr placeholder_start = it->lower();
|
const VAddr placeholder_start = it->lower();
|
||||||
const VAddr placeholder_end = it->upper();
|
const VAddr placeholder_end = it->upper();
|
||||||
const VAddr virtual_end = virtual_addr + size;
|
const VAddr virtual_end = virtual_addr + aligned_size;
|
||||||
|
|
||||||
// If the placeholder doesn't exactly start at virtual_addr, split it at the start.
|
// If the placeholder doesn't exactly start at virtual_addr, split it at the start.
|
||||||
if (placeholder_start != virtual_addr) {
|
if (placeholder_start != virtual_addr) {
|
||||||
|
@ -161,11 +163,23 @@ struct AddressSpace::Impl {
|
||||||
void* ptr = nullptr;
|
void* ptr = nullptr;
|
||||||
if (phys_addr != -1) {
|
if (phys_addr != -1) {
|
||||||
HANDLE backing = fd ? reinterpret_cast<HANDLE>(fd) : backing_handle;
|
HANDLE backing = fd ? reinterpret_cast<HANDLE>(fd) : backing_handle;
|
||||||
ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr), phys_addr,
|
if (fd && prot == PAGE_READONLY) {
|
||||||
size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
DWORD resultvar;
|
||||||
|
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), aligned_size,
|
||||||
|
MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
|
||||||
|
PAGE_READWRITE, nullptr, 0);
|
||||||
|
bool ret = ReadFile(backing, ptr, size, &resultvar, NULL);
|
||||||
|
ASSERT_MSG(ret, "ReadFile failed. {}", Common::GetLastErrorMsg());
|
||||||
|
ret = VirtualProtect(ptr, size, prot, &resultvar);
|
||||||
|
ASSERT_MSG(ret, "VirtualProtect failed. {}", Common::GetLastErrorMsg());
|
||||||
|
} else {
|
||||||
|
ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr),
|
||||||
|
phys_addr, aligned_size, MEM_REPLACE_PLACEHOLDER, prot,
|
||||||
|
nullptr, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ptr =
|
ptr =
|
||||||
VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), aligned_size,
|
||||||
MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||||
}
|
}
|
||||||
ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg());
|
ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg());
|
||||||
|
@ -455,12 +469,12 @@ void* AddressSpace::MapFile(VAddr virtual_addr, size_t size, size_t offset, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddressSpace::Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VAddr end_in_vma,
|
void AddressSpace::Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VAddr end_in_vma,
|
||||||
PAddr phys_base, bool is_exec, bool has_backing) {
|
PAddr phys_base, bool is_exec, bool has_backing, bool readonly_file) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// There does not appear to be comparable support for partial unmapping on Windows.
|
// There does not appear to be comparable support for partial unmapping on Windows.
|
||||||
// Unfortunately, a least one title was found to require this. The workaround is to unmap
|
// Unfortunately, a least one title was found to require this. The workaround is to unmap
|
||||||
// the entire allocation and remap the portions outside of the requested unmapping range.
|
// the entire allocation and remap the portions outside of the requested unmapping range.
|
||||||
impl->Unmap(virtual_addr, size, has_backing);
|
impl->Unmap(virtual_addr, size, has_backing && !readonly_file);
|
||||||
|
|
||||||
// TODO: Determine if any titles require partial unmapping support for flexible allocations.
|
// TODO: Determine if any titles require partial unmapping support for flexible allocations.
|
||||||
ASSERT_MSG(has_backing || (start_in_vma == 0 && end_in_vma == size),
|
ASSERT_MSG(has_backing || (start_in_vma == 0 && end_in_vma == size),
|
||||||
|
|
|
@ -92,7 +92,7 @@ public:
|
||||||
|
|
||||||
/// Unmaps specified virtual memory area.
|
/// Unmaps specified virtual memory area.
|
||||||
void Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VAddr end_in_vma,
|
void Unmap(VAddr virtual_addr, size_t size, VAddr start_in_vma, VAddr end_in_vma,
|
||||||
PAddr phys_base, bool is_exec, bool has_backing);
|
PAddr phys_base, bool is_exec, bool has_backing, bool readonly_file);
|
||||||
|
|
||||||
void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms);
|
void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms);
|
||||||
|
|
||||||
|
|
|
@ -114108,7 +114108,7 @@ STUB(
|
||||||
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
|
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
|
||||||
STUB("efPahl2FufA",
|
STUB("efPahl2FufA",
|
||||||
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
|
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
|
||||||
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlemetId)
|
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlementId)
|
||||||
STUB("efXnxYFN5oE", _ZNSt11range_errorD0Ev)
|
STUB("efXnxYFN5oE", _ZNSt11range_errorD0Ev)
|
||||||
STUB("efcwuDLsAM0", _ZThn120_NK7WebCore16HTMLMediaElement5mutedEv)
|
STUB("efcwuDLsAM0", _ZThn120_NK7WebCore16HTMLMediaElement5mutedEv)
|
||||||
STUB("efhGArzWdxE", _ZN7bmalloc6IsoTLS15s_didInitializeE)
|
STUB("efhGArzWdxE", _ZN7bmalloc6IsoTLS15s_didInitializeE)
|
||||||
|
@ -129493,7 +129493,7 @@ STUB(
|
||||||
STUB("kJlYH5uMAWI", sceNetResolverDestroy)
|
STUB("kJlYH5uMAWI", sceNetResolverDestroy)
|
||||||
STUB("kJmdxo4uM+8",
|
STUB("kJmdxo4uM+8",
|
||||||
_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE5_InitERKSt8_Locinfo)
|
_ZNSt9money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE5_InitERKSt8_Locinfo)
|
||||||
STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlemetId)
|
STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlementId)
|
||||||
STUB(
|
STUB(
|
||||||
"kJoY9lMIFzY",
|
"kJoY9lMIFzY",
|
||||||
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)
|
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace Core::AeroLib {
|
||||||
// on lookup, setting up the nid_entry they are matched with
|
// on lookup, setting up the nid_entry they are matched with
|
||||||
//
|
//
|
||||||
// If it runs out of stubs with name information, it will return
|
// If it runs out of stubs with name information, it will return
|
||||||
// a default implemetnation without function name details
|
// a default implementation without function name details
|
||||||
|
|
||||||
// Up to 512, larger values lead to more resolve stub slots
|
// Up to 512, larger values lead to more resolve stub slots
|
||||||
// and to longer compile / CI times
|
// and to longer compile / CI times
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
#include <half.hpp>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,6 +31,12 @@ static Xbyak::Reg ZydisToXbyakRegister(const ZydisRegister reg) {
|
||||||
if (reg >= ZYDIS_REGISTER_RAX && reg <= ZYDIS_REGISTER_R15) {
|
if (reg >= ZYDIS_REGISTER_RAX && reg <= ZYDIS_REGISTER_R15) {
|
||||||
return Xbyak::Reg64(reg - ZYDIS_REGISTER_RAX + Xbyak::Operand::RAX);
|
return Xbyak::Reg64(reg - ZYDIS_REGISTER_RAX + Xbyak::Operand::RAX);
|
||||||
}
|
}
|
||||||
|
if (reg >= ZYDIS_REGISTER_XMM0 && reg <= ZYDIS_REGISTER_XMM31) {
|
||||||
|
return Xbyak::Xmm(reg - ZYDIS_REGISTER_XMM0 + xmm0.getIdx());
|
||||||
|
}
|
||||||
|
if (reg >= ZYDIS_REGISTER_YMM0 && reg <= ZYDIS_REGISTER_YMM31) {
|
||||||
|
return Xbyak::Ymm(reg - ZYDIS_REGISTER_YMM0 + ymm0.getIdx());
|
||||||
|
}
|
||||||
UNREACHABLE_MSG("Unsupported register: {}", static_cast<u32>(reg));
|
UNREACHABLE_MSG("Unsupported register: {}", static_cast<u32>(reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +73,12 @@ static Xbyak::Address ZydisToXbyakMemoryOperand(const ZydisDecodedOperand& opera
|
||||||
return ptr[expression];
|
return ptr[expression];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u64 ZydisToXbyakImmediateOperand(const ZydisDecodedOperand& operand) {
|
||||||
|
ASSERT_MSG(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE,
|
||||||
|
"Expected immediate operand, got type: {}", static_cast<u32>(operand.type));
|
||||||
|
return operand.imm.value.u;
|
||||||
|
}
|
||||||
|
|
||||||
static std::unique_ptr<Xbyak::Operand> ZydisToXbyakOperand(const ZydisDecodedOperand& operand) {
|
static std::unique_ptr<Xbyak::Operand> ZydisToXbyakOperand(const ZydisDecodedOperand& operand) {
|
||||||
switch (operand.type) {
|
switch (operand.type) {
|
||||||
case ZYDIS_OPERAND_TYPE_REGISTER: {
|
case ZYDIS_OPERAND_TYPE_REGISTER: {
|
||||||
|
@ -110,51 +123,135 @@ static Xbyak::Reg AllocateScratchRegister(
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
static constexpr u32 MaxSavedRegisters = 3;
|
static pthread_key_t stack_pointer_slot;
|
||||||
static pthread_key_t register_save_slots[MaxSavedRegisters];
|
static pthread_key_t patch_stack_slot;
|
||||||
static std::once_flag register_save_init_flag;
|
static std::once_flag patch_context_slots_init_flag;
|
||||||
|
|
||||||
static_assert(sizeof(void*) == sizeof(u64),
|
static_assert(sizeof(void*) == sizeof(u64),
|
||||||
"Cannot fit a register inside a thread local storage slot.");
|
"Cannot fit a register inside a thread local storage slot.");
|
||||||
|
|
||||||
static void InitializeRegisterSaveSlots() {
|
static void InitializePatchContextSlots() {
|
||||||
for (u32 i = 0; i < MaxSavedRegisters; i++) {
|
ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0,
|
||||||
ASSERT_MSG(pthread_key_create(®ister_save_slots[i], nullptr) == 0,
|
"Unable to allocate thread-local register for stack pointer.");
|
||||||
"Unable to allocate thread-local register save slot {}", i);
|
ASSERT_MSG(pthread_key_create(&patch_stack_slot, nullptr) == 0,
|
||||||
|
"Unable to allocate thread-local register for patch stack.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeThreadPatchStack() {
|
||||||
|
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||||
|
|
||||||
|
const auto* patch_stack = std::malloc(0x1000);
|
||||||
|
pthread_setspecific(patch_stack_slot, patch_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupThreadPatchStack() {
|
||||||
|
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||||
|
|
||||||
|
auto* patch_stack = pthread_getspecific(patch_stack_slot);
|
||||||
|
if (patch_stack != nullptr) {
|
||||||
|
std::free(patch_stack);
|
||||||
|
pthread_setspecific(patch_stack_slot, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
|
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||||
ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to save {} registers.",
|
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||||
regs.size());
|
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||||
|
|
||||||
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
|
|
||||||
|
|
||||||
u32 index = 0;
|
|
||||||
for (const auto& reg : regs) {
|
|
||||||
const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
|
|
||||||
|
|
||||||
|
// Save stack pointer and load patch stack.
|
||||||
c.putSeg(gs);
|
c.putSeg(gs);
|
||||||
c.mov(qword[offset], reg.cvt64());
|
c.mov(qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))], rsp);
|
||||||
}
|
c.putSeg(gs);
|
||||||
|
c.mov(rsp, qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Restores the stack pointer from thread local storage.
|
||||||
|
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||||
|
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||||
|
|
||||||
|
// Save patch stack pointer and load original stack.
|
||||||
|
c.putSeg(gs);
|
||||||
|
c.mov(qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))], rsp);
|
||||||
|
c.putSeg(gs);
|
||||||
|
c.mov(rsp, qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// These utilities are not implemented as we can't save anything to thread local storage without
|
||||||
|
// temporary registers.
|
||||||
|
void InitializeThreadPatchStack() {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanupThreadPatchStack() {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||||
|
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restores the stack pointer from thread local storage.
|
||||||
|
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||||
|
UNIMPLEMENTED();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Switches to the patch stack, saves registers, and restores the original stack.
|
||||||
|
static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
|
||||||
|
SaveStack(c);
|
||||||
|
for (const auto& reg : regs) {
|
||||||
|
c.push(reg.cvt64());
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Switches to the patch stack, restores registers, and restores the original stack.
|
||||||
static void RestoreRegisters(Xbyak::CodeGenerator& c,
|
static void RestoreRegisters(Xbyak::CodeGenerator& c,
|
||||||
const std::initializer_list<Xbyak::Reg> regs) {
|
const std::initializer_list<Xbyak::Reg> regs) {
|
||||||
ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to restore {} registers.",
|
SaveStack(c);
|
||||||
regs.size());
|
|
||||||
|
|
||||||
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
|
|
||||||
|
|
||||||
u32 index = 0;
|
|
||||||
for (const auto& reg : regs) {
|
for (const auto& reg : regs) {
|
||||||
const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
|
c.pop(reg.cvt64());
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
c.putSeg(gs);
|
/// Switches to the patch stack and stores all registers.
|
||||||
c.mov(reg.cvt64(), qword[offset]);
|
static void SaveContext(Xbyak::CodeGenerator& c) {
|
||||||
|
SaveStack(c);
|
||||||
|
for (int reg = Xbyak::Operand::RAX; reg <= Xbyak::Operand::R15; reg++) {
|
||||||
|
c.push(Xbyak::Reg64(reg));
|
||||||
|
}
|
||||||
|
for (int reg = 0; reg <= 7; reg++) {
|
||||||
|
c.sub(rsp, 32);
|
||||||
|
c.vmovdqu(ptr[rsp], Xbyak::Ymm(reg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Restores all registers and restores the original stack.
|
||||||
|
/// If the destination is a register, it is not restored to preserve the output.
|
||||||
|
static void RestoreContext(Xbyak::CodeGenerator& c, const Xbyak::Operand& dst) {
|
||||||
|
for (int reg = 7; reg >= 0; reg--) {
|
||||||
|
if ((!dst.isXMM() && !dst.isYMM()) || dst.getIdx() != reg) {
|
||||||
|
c.vmovdqu(Xbyak::Ymm(reg), ptr[rsp]);
|
||||||
|
}
|
||||||
|
c.add(rsp, 32);
|
||||||
|
}
|
||||||
|
for (int reg = Xbyak::Operand::R15; reg >= Xbyak::Operand::RAX; reg--) {
|
||||||
|
if (!dst.isREG() || dst.getIdx() != reg) {
|
||||||
|
c.pop(Xbyak::Reg64(reg));
|
||||||
|
} else {
|
||||||
|
c.add(rsp, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
|
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
|
||||||
|
@ -204,9 +301,9 @@ static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
||||||
c.and_(dst, scratch2);
|
c.and_(dst, scratch2);
|
||||||
|
|
||||||
if (dst.getIdx() == shift.getIdx()) {
|
if (dst.getIdx() == shift.getIdx()) {
|
||||||
RestoreRegisters(c, {scratch1, scratch2});
|
RestoreRegisters(c, {scratch2, scratch1});
|
||||||
} else {
|
} else {
|
||||||
RestoreRegisters(c, {scratch1, scratch2, shift});
|
RestoreRegisters(c, {shift, scratch2, scratch1});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,10 +355,138 @@ static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
|
||||||
RestoreRegisters(c, {scratch});
|
RestoreRegisters(c, {scratch});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
static __attribute__((sysv_abi)) void PerformVCVTPH2PS(float* out, const half_float::half* in,
|
||||||
|
const u32 count) {
|
||||||
|
for (u32 i = 0; i < count; i++) {
|
||||||
|
out[i] = half_float::half_cast<float>(in[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateVCVTPH2PS(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
|
||||||
|
const auto float_count = dst.getBit() / 32;
|
||||||
|
const auto byte_count = float_count * 4;
|
||||||
|
|
||||||
|
SaveContext(c);
|
||||||
|
|
||||||
|
// Allocate stack space for outputs and load into first parameter.
|
||||||
|
c.sub(rsp, byte_count);
|
||||||
|
c.mov(rdi, rsp);
|
||||||
|
|
||||||
|
if (src->isXMM()) {
|
||||||
|
// Allocate stack space for inputs and load into second parameter.
|
||||||
|
c.sub(rsp, byte_count);
|
||||||
|
c.mov(rsi, rsp);
|
||||||
|
|
||||||
|
// Move input to the allocated space.
|
||||||
|
c.movdqu(ptr[rsp], *reinterpret_cast<Xbyak::Xmm*>(src.get()));
|
||||||
|
} else {
|
||||||
|
c.lea(rsi, src->getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load float count into third parameter.
|
||||||
|
c.mov(rdx, float_count);
|
||||||
|
|
||||||
|
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPH2PS));
|
||||||
|
c.call(rax);
|
||||||
|
|
||||||
|
if (src->isXMM()) {
|
||||||
|
// Clean up after inputs space.
|
||||||
|
c.add(rsp, byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load outputs into destination register and clean up space.
|
||||||
|
if (dst.isYMM()) {
|
||||||
|
c.vmovdqu(*reinterpret_cast<const Xbyak::Ymm*>(&dst), ptr[rsp]);
|
||||||
|
} else {
|
||||||
|
c.movdqu(*reinterpret_cast<const Xbyak::Xmm*>(&dst), ptr[rsp]);
|
||||||
|
}
|
||||||
|
c.add(rsp, byte_count);
|
||||||
|
|
||||||
|
RestoreContext(c, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
using SingleToHalfFloatConverter = half_float::half (*)(float);
|
||||||
|
static const SingleToHalfFloatConverter SingleToHalfFloatConverters[4] = {
|
||||||
|
half_float::half_cast<half_float::half, std::round_to_nearest, float>,
|
||||||
|
half_float::half_cast<half_float::half, std::round_toward_neg_infinity, float>,
|
||||||
|
half_float::half_cast<half_float::half, std::round_toward_infinity, float>,
|
||||||
|
half_float::half_cast<half_float::half, std::round_toward_zero, float>,
|
||||||
|
};
|
||||||
|
|
||||||
|
static __attribute__((sysv_abi)) void PerformVCVTPS2PH(half_float::half* out, const float* in,
|
||||||
|
const u32 count, const u8 rounding_mode) {
|
||||||
|
const auto conversion_func = SingleToHalfFloatConverters[rounding_mode];
|
||||||
|
|
||||||
|
for (u32 i = 0; i < count; i++) {
|
||||||
|
out[i] = conversion_func(in[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateVCVTPS2PH(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakRegisterOperand(operands[1]);
|
||||||
|
const auto ctrl = ZydisToXbyakImmediateOperand(operands[2]);
|
||||||
|
|
||||||
|
const auto float_count = src.getBit() / 32;
|
||||||
|
const auto byte_count = float_count * 4;
|
||||||
|
|
||||||
|
SaveContext(c);
|
||||||
|
|
||||||
|
if (dst->isXMM()) {
|
||||||
|
// Allocate stack space for outputs and load into first parameter.
|
||||||
|
c.sub(rsp, byte_count);
|
||||||
|
c.mov(rdi, rsp);
|
||||||
|
} else {
|
||||||
|
c.lea(rdi, dst->getAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate stack space for inputs and load into second parameter.
|
||||||
|
c.sub(rsp, byte_count);
|
||||||
|
c.mov(rsi, rsp);
|
||||||
|
|
||||||
|
// Move input to the allocated space.
|
||||||
|
if (src.isYMM()) {
|
||||||
|
c.vmovdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Ymm*>(&src));
|
||||||
|
} else {
|
||||||
|
c.movdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Xmm*>(&src));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load float count into third parameter.
|
||||||
|
c.mov(rdx, float_count);
|
||||||
|
|
||||||
|
// Load rounding mode into fourth parameter.
|
||||||
|
if (ctrl & 4) {
|
||||||
|
// Load from MXCSR.RC.
|
||||||
|
c.stmxcsr(ptr[rsp - 4]);
|
||||||
|
c.mov(rcx, ptr[rsp - 4]);
|
||||||
|
c.shr(rcx, 13);
|
||||||
|
c.and_(rcx, 3);
|
||||||
|
} else {
|
||||||
|
c.mov(rcx, ctrl & 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPS2PH));
|
||||||
|
c.call(rax);
|
||||||
|
|
||||||
|
// Clean up after inputs space.
|
||||||
|
c.add(rsp, byte_count);
|
||||||
|
|
||||||
|
if (dst->isXMM()) {
|
||||||
|
// Load outputs into destination register and clean up space.
|
||||||
|
c.movdqu(*reinterpret_cast<Xbyak::Xmm*>(dst.get()), ptr[rsp]);
|
||||||
|
c.add(rsp, byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
RestoreContext(c, *dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
size_t size = sizeof(ret);
|
size_t size = sizeof(ret);
|
||||||
if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) != 0) {
|
if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -339,12 +564,16 @@ static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
// BMI1 instructions that are not supported by Rosetta 2 on Apple Silicon.
|
// Patches for instruction sets not supported by Rosetta 2.
|
||||||
|
// BMI1
|
||||||
{ZYDIS_MNEMONIC_ANDN, {FilterRosetta2Only, GenerateANDN, true}},
|
{ZYDIS_MNEMONIC_ANDN, {FilterRosetta2Only, GenerateANDN, true}},
|
||||||
{ZYDIS_MNEMONIC_BEXTR, {FilterRosetta2Only, GenerateBEXTR, true}},
|
{ZYDIS_MNEMONIC_BEXTR, {FilterRosetta2Only, GenerateBEXTR, true}},
|
||||||
{ZYDIS_MNEMONIC_BLSI, {FilterRosetta2Only, GenerateBLSI, true}},
|
{ZYDIS_MNEMONIC_BLSI, {FilterRosetta2Only, GenerateBLSI, true}},
|
||||||
{ZYDIS_MNEMONIC_BLSMSK, {FilterRosetta2Only, GenerateBLSMSK, true}},
|
{ZYDIS_MNEMONIC_BLSMSK, {FilterRosetta2Only, GenerateBLSMSK, true}},
|
||||||
{ZYDIS_MNEMONIC_BLSR, {FilterRosetta2Only, GenerateBLSR, true}},
|
{ZYDIS_MNEMONIC_BLSR, {FilterRosetta2Only, GenerateBLSR, true}},
|
||||||
|
// F16C
|
||||||
|
{ZYDIS_MNEMONIC_VCVTPH2PS, {FilterRosetta2Only, GenerateVCVTPH2PS, true}},
|
||||||
|
{ZYDIS_MNEMONIC_VCVTPS2PH, {FilterRosetta2Only, GenerateVCVTPS2PH, true}},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,12 @@ class CodeGenerator;
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
/// Initializes a stack for the current thread for use by patch implementations.
|
||||||
|
void InitializeThreadPatchStack();
|
||||||
|
|
||||||
|
/// Cleans up the patch stack for the current thread.
|
||||||
|
void CleanupThreadPatchStack();
|
||||||
|
|
||||||
/// Patches CPU instructions that cannot run as-is on the host.
|
/// Patches CPU instructions that cannot run as-is on the host.
|
||||||
void PatchInstructions(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
void PatchInstructions(u64 segment_addr, u64 segment_size, Xbyak::CodeGenerator& c);
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
||||||
CryptoPP::InvertibleRSAFunction params;
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
params.SetPrime1(CryptoPP::Integer(pkg_derived_key3_keyset.Prime1, 0x80));
|
params.SetPrime1(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime1, 0x80));
|
||||||
params.SetPrime2(CryptoPP::Integer(pkg_derived_key3_keyset.Prime2, 0x80));
|
params.SetPrime2(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime2, 0x80));
|
||||||
|
|
||||||
params.SetPublicExponent(CryptoPP::Integer(pkg_derived_key3_keyset.PublicExponent, 4));
|
params.SetPublicExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PublicExponent, 4));
|
||||||
params.SetPrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.PrivateExponent, 0x100));
|
params.SetPrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PrivateExponent, 0x100));
|
||||||
|
|
||||||
params.SetModPrime1PrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.Exponent1, 0x80));
|
params.SetModPrime1PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent1, 0x80));
|
||||||
params.SetModPrime2PrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.Exponent2, 0x80));
|
params.SetModPrime2PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent2, 0x80));
|
||||||
|
|
||||||
params.SetModulus(CryptoPP::Integer(pkg_derived_key3_keyset.Modulus, 0x100));
|
params.SetModulus(CryptoPP::Integer(PkgDerivedKey3Keyset::Modulus, 0x100));
|
||||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
CryptoPP::Integer(pkg_derived_key3_keyset.Coefficient, 0x80));
|
CryptoPP::Integer(PkgDerivedKey3Keyset::Coefficient, 0x80));
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
@ -26,18 +26,18 @@ CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey Crypto::FakeKeyset_keyset_init() {
|
CryptoPP::RSA::PrivateKey Crypto::FakeKeyset_keyset_init() {
|
||||||
CryptoPP::InvertibleRSAFunction params;
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
params.SetPrime1(CryptoPP::Integer(FakeKeyset_keyset.Prime1, 0x80));
|
params.SetPrime1(CryptoPP::Integer(FakeKeyset::Prime1, 0x80));
|
||||||
params.SetPrime2(CryptoPP::Integer(FakeKeyset_keyset.Prime2, 0x80));
|
params.SetPrime2(CryptoPP::Integer(FakeKeyset::Prime2, 0x80));
|
||||||
|
|
||||||
params.SetPublicExponent(CryptoPP::Integer(FakeKeyset_keyset.PublicExponent, 4));
|
params.SetPublicExponent(CryptoPP::Integer(FakeKeyset::PublicExponent, 4));
|
||||||
params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.PrivateExponent, 0x100));
|
params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset::PrivateExponent, 0x100));
|
||||||
|
|
||||||
params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.Exponent1, 0x80));
|
params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent1, 0x80));
|
||||||
params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.Exponent2, 0x80));
|
params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent2, 0x80));
|
||||||
|
|
||||||
params.SetModulus(CryptoPP::Integer(FakeKeyset_keyset.Modulus, 0x100));
|
params.SetModulus(CryptoPP::Integer(FakeKeyset::Modulus, 0x100));
|
||||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
CryptoPP::Integer(FakeKeyset_keyset.Coefficient, 0x80));
|
CryptoPP::Integer(FakeKeyset::Coefficient, 0x80));
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
@ -46,25 +46,22 @@ CryptoPP::RSA::PrivateKey Crypto::FakeKeyset_keyset_init() {
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey Crypto::DebugRifKeyset_init() {
|
CryptoPP::RSA::PrivateKey Crypto::DebugRifKeyset_init() {
|
||||||
CryptoPP::InvertibleRSAFunction params;
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
params.SetPrime1(
|
params.SetPrime1(CryptoPP::Integer(DebugRifKeyset::Prime1, sizeof(DebugRifKeyset::Prime1)));
|
||||||
CryptoPP::Integer(DebugRifKeyset_keyset.Prime1, sizeof(DebugRifKeyset_keyset.Prime1)));
|
params.SetPrime2(CryptoPP::Integer(DebugRifKeyset::Prime2, sizeof(DebugRifKeyset::Prime2)));
|
||||||
params.SetPrime2(
|
|
||||||
CryptoPP::Integer(DebugRifKeyset_keyset.Prime2, sizeof(DebugRifKeyset_keyset.Prime2)));
|
|
||||||
|
|
||||||
params.SetPublicExponent(CryptoPP::Integer(DebugRifKeyset_keyset.PrivateExponent,
|
params.SetPublicExponent(
|
||||||
sizeof(DebugRifKeyset_keyset.PrivateExponent)));
|
CryptoPP::Integer(DebugRifKeyset::PublicExponent, sizeof(DebugRifKeyset::PublicExponent)));
|
||||||
params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.PrivateExponent,
|
params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset::PrivateExponent,
|
||||||
sizeof(DebugRifKeyset_keyset.PrivateExponent)));
|
sizeof(DebugRifKeyset::PrivateExponent)));
|
||||||
|
|
||||||
params.SetModPrime1PrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.Exponent1,
|
params.SetModPrime1PrivateExponent(
|
||||||
sizeof(DebugRifKeyset_keyset.Exponent1)));
|
CryptoPP::Integer(DebugRifKeyset::Exponent1, sizeof(DebugRifKeyset::Exponent1)));
|
||||||
params.SetModPrime2PrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.Exponent2,
|
params.SetModPrime2PrivateExponent(
|
||||||
sizeof(DebugRifKeyset_keyset.Exponent2)));
|
CryptoPP::Integer(DebugRifKeyset::Exponent2, sizeof(DebugRifKeyset::Exponent2)));
|
||||||
|
|
||||||
params.SetModulus(
|
params.SetModulus(CryptoPP::Integer(DebugRifKeyset::Modulus, sizeof(DebugRifKeyset::Modulus)));
|
||||||
CryptoPP::Integer(DebugRifKeyset_keyset.Modulus, sizeof(DebugRifKeyset_keyset.Modulus)));
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
params.SetMultiplicativeInverseOfPrime2ModPrime1(CryptoPP::Integer(
|
CryptoPP::Integer(DebugRifKeyset::Coefficient, sizeof(DebugRifKeyset::Coefficient)));
|
||||||
DebugRifKeyset_keyset.Coefficient, sizeof(DebugRifKeyset_keyset.Coefficient)));
|
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey privateKey(params);
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,6 @@
|
||||||
|
|
||||||
class Crypto {
|
class Crypto {
|
||||||
public:
|
public:
|
||||||
PkgDerivedKey3Keyset pkg_derived_key3_keyset;
|
|
||||||
FakeKeyset FakeKeyset_keyset;
|
|
||||||
DebugRifKeyset DebugRifKeyset_keyset;
|
|
||||||
|
|
||||||
CryptoPP::RSA::PrivateKey key_pkg_derived_key3_keyset_init();
|
CryptoPP::RSA::PrivateKey key_pkg_derived_key3_keyset_init();
|
||||||
CryptoPP::RSA::PrivateKey FakeKeyset_keyset_init();
|
CryptoPP::RSA::PrivateKey FakeKeyset_keyset_init();
|
||||||
CryptoPP::RSA::PrivateKey DebugRifKeyset_init();
|
CryptoPP::RSA::PrivateKey DebugRifKeyset_init();
|
||||||
|
|
|
@ -7,384 +7,299 @@
|
||||||
class FakeKeyset {
|
class FakeKeyset {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
// Constructor
|
||||||
const CryptoPP::byte* Exponent1;
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0x6D, 0x48, 0xE0, 0x54, 0x40, 0x25, 0xC8, 0x41, 0x29, 0x52, 0x42, 0x27, 0xEB, 0xD2, 0xC7,
|
||||||
|
0xAB, 0x6B, 0x9C, 0x27, 0x0A, 0xB4, 0x1F, 0x94, 0x4E, 0xFA, 0x42, 0x1D, 0xB7, 0xBC, 0xB9,
|
||||||
|
0xAE, 0xBC, 0x04, 0x6F, 0x75, 0x8F, 0x10, 0x5F, 0x89, 0xAC, 0xAB, 0x9C, 0xD2, 0xFA, 0xE6,
|
||||||
|
0xA4, 0x13, 0x83, 0x68, 0xD4, 0x56, 0x38, 0xFE, 0xE5, 0x2B, 0x78, 0x44, 0x9C, 0x34, 0xE6,
|
||||||
|
0x5A, 0xA0, 0xBE, 0x05, 0x70, 0xAD, 0x15, 0xC3, 0x2D, 0x31, 0xAC, 0x97, 0x5D, 0x88, 0xFC,
|
||||||
|
0xC1, 0x62, 0x3D, 0xE2, 0xED, 0x11, 0xDB, 0xB6, 0x9E, 0xFC, 0x5A, 0x5A, 0x03, 0xF6, 0xCF,
|
||||||
|
0x08, 0xD4, 0x5D, 0x90, 0xC9, 0x2A, 0xB9, 0x9B, 0xCF, 0xC8, 0x1A, 0x65, 0xF3, 0x5B, 0xE8,
|
||||||
|
0x7F, 0xCF, 0xA5, 0xA6, 0x4C, 0x5C, 0x2A, 0x12, 0x0F, 0x92, 0xA5, 0xE3, 0xF0, 0x17, 0x1E,
|
||||||
|
0x9A, 0x97, 0x45, 0x86, 0xFD, 0xDB, 0x54, 0x25};
|
||||||
// exponent2 = d mod (q - 1)
|
// exponent2 = d mod (q - 1)
|
||||||
const CryptoPP::byte* Exponent2;
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0x2A, 0x51, 0xCE, 0x02, 0x44, 0x28, 0x50, 0xE8, 0x30, 0x20, 0x7C, 0x9C, 0x55, 0xBF, 0x60,
|
||||||
|
0x39, 0xBC, 0xD1, 0xF0, 0xE7, 0x68, 0xF8, 0x08, 0x5B, 0x61, 0x1F, 0xA7, 0xBF, 0xD0, 0xE8,
|
||||||
|
0x8B, 0xB5, 0xB1, 0xD5, 0xD9, 0x16, 0xAC, 0x75, 0x0C, 0x6D, 0xF2, 0xE0, 0xB5, 0x97, 0x75,
|
||||||
|
0xD2, 0x68, 0x16, 0x1F, 0x00, 0x7D, 0x8B, 0x17, 0xE8, 0x78, 0x48, 0x41, 0x71, 0x2B, 0x18,
|
||||||
|
0x96, 0x80, 0x11, 0xDB, 0x68, 0x39, 0x9C, 0xD6, 0xE0, 0x72, 0x42, 0x86, 0xF0, 0x1B, 0x16,
|
||||||
|
0x0D, 0x3E, 0x12, 0x94, 0x3D, 0x25, 0xA8, 0xA9, 0x30, 0x9E, 0x54, 0x5A, 0xD6, 0x36, 0x6C,
|
||||||
|
0xD6, 0x8C, 0x20, 0x62, 0x8F, 0xA1, 0x6B, 0x1F, 0x7C, 0x6D, 0xB2, 0xB1, 0xC1, 0x2E, 0xAD,
|
||||||
|
0x36, 0x02, 0x9C, 0x3A, 0xCA, 0x2F, 0x09, 0xD2, 0x45, 0x9E, 0xEB, 0xF2, 0xBC, 0x6C, 0xAA,
|
||||||
|
0x3B, 0x3E, 0x90, 0xBC, 0x38, 0x67, 0x35, 0x4D};
|
||||||
// e
|
// e
|
||||||
const CryptoPP::byte* PublicExponent;
|
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||||
// (InverseQ)(q) = 1 mod p
|
// (InverseQ)(q) = 1 mod p
|
||||||
const CryptoPP::byte* Coefficient;
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0x0B, 0x67, 0x1C, 0x0D, 0x6C, 0x57, 0xD3, 0xE7, 0x05, 0x65, 0x94, 0x31, 0x56, 0x55, 0xFD,
|
||||||
|
0x28, 0x08, 0xFA, 0x05, 0x8A, 0xCC, 0x55, 0x39, 0x61, 0x97, 0x63, 0xA0, 0x16, 0x27, 0x3D,
|
||||||
|
0xED, 0xC1, 0x16, 0x40, 0x2A, 0x12, 0xEA, 0x6F, 0xD9, 0xD8, 0x58, 0x56, 0xA8, 0x56, 0x8B,
|
||||||
|
0x0D, 0x38, 0x5E, 0x1E, 0x80, 0x3B, 0x5F, 0x40, 0x80, 0x6F, 0x62, 0x4F, 0x28, 0xA2, 0x69,
|
||||||
|
0xF3, 0xD3, 0xF7, 0xFD, 0xB2, 0xC3, 0x52, 0x43, 0x20, 0x92, 0x9D, 0x97, 0x8D, 0xA0, 0x15,
|
||||||
|
0x07, 0x15, 0x6E, 0xA4, 0x0D, 0x56, 0xD3, 0x37, 0x1A, 0xC4, 0x9E, 0xDF, 0x02, 0x49, 0xB8,
|
||||||
|
0x0A, 0x84, 0x62, 0xF5, 0xFA, 0xB9, 0x3F, 0xA4, 0x09, 0x76, 0xCC, 0xAA, 0xB9, 0x9B, 0xA6,
|
||||||
|
0x4F, 0xC1, 0x6A, 0x64, 0xCE, 0xD8, 0x77, 0xAB, 0x4B, 0xF9, 0xA0, 0xAE, 0xDA, 0xF1, 0x67,
|
||||||
|
0x87, 0x7C, 0x98, 0x5C, 0x7E, 0xB8, 0x73, 0xF5};
|
||||||
// n = p * q
|
// n = p * q
|
||||||
const CryptoPP::byte* Modulus;
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xC6, 0xCF, 0x71, 0xE7, 0xE5, 0x9A, 0xF0, 0xD1, 0x2A, 0x2C, 0x45, 0x8B, 0xF9, 0x2A, 0x0E,
|
||||||
|
0xC1, 0x43, 0x05, 0x8B, 0xC3, 0x71, 0x17, 0x80, 0x1D, 0xCD, 0x49, 0x7D, 0xDE, 0x35, 0x9D,
|
||||||
|
0x25, 0x9B, 0xA0, 0xD7, 0xA0, 0xF2, 0x7D, 0x6C, 0x08, 0x7E, 0xAA, 0x55, 0x02, 0x68, 0x2B,
|
||||||
|
0x23, 0xC6, 0x44, 0xB8, 0x44, 0x18, 0xEB, 0x56, 0xCF, 0x16, 0xA2, 0x48, 0x03, 0xC9, 0xE7,
|
||||||
|
0x4F, 0x87, 0xEB, 0x3D, 0x30, 0xC3, 0x15, 0x88, 0xBF, 0x20, 0xE7, 0x9D, 0xFF, 0x77, 0x0C,
|
||||||
|
0xDE, 0x1D, 0x24, 0x1E, 0x63, 0xA9, 0x4F, 0x8A, 0xBF, 0x5B, 0xBE, 0x60, 0x19, 0x68, 0x33,
|
||||||
|
0x3B, 0xFC, 0xED, 0x9F, 0x47, 0x4E, 0x5F, 0xF8, 0xEA, 0xCB, 0x3D, 0x00, 0xBD, 0x67, 0x01,
|
||||||
|
0xF9, 0x2C, 0x6D, 0xC6, 0xAC, 0x13, 0x64, 0xE7, 0x67, 0x14, 0xF3, 0xDC, 0x52, 0x69, 0x6A,
|
||||||
|
0xB9, 0x83, 0x2C, 0x42, 0x30, 0x13, 0x1B, 0xB2, 0xD8, 0xA5, 0x02, 0x0D, 0x79, 0xED, 0x96,
|
||||||
|
0xB1, 0x0D, 0xF8, 0xCC, 0x0C, 0xDF, 0x81, 0x95, 0x4F, 0x03, 0x58, 0x09, 0x57, 0x0E, 0x80,
|
||||||
|
0x69, 0x2E, 0xFE, 0xFF, 0x52, 0x77, 0xEA, 0x75, 0x28, 0xA8, 0xFB, 0xC9, 0xBE, 0xBF, 0x9F,
|
||||||
|
0xBB, 0xB7, 0x79, 0x8E, 0x18, 0x05, 0xE1, 0x80, 0xBD, 0x50, 0x34, 0x94, 0x81, 0xD3, 0x53,
|
||||||
|
0xC2, 0x69, 0xA2, 0xD2, 0x4C, 0xCF, 0x6C, 0xF4, 0x57, 0x2C, 0x10, 0x4A, 0x3F, 0xFB, 0x22,
|
||||||
|
0xFD, 0x8B, 0x97, 0xE2, 0xC9, 0x5B, 0xA6, 0x2B, 0xCD, 0xD6, 0x1B, 0x6B, 0xDB, 0x68, 0x7F,
|
||||||
|
0x4B, 0xC2, 0xA0, 0x50, 0x34, 0xC0, 0x05, 0xE5, 0x8D, 0xEF, 0x24, 0x67, 0xFF, 0x93, 0x40,
|
||||||
|
0xCF, 0x2D, 0x62, 0xA2, 0xA0, 0x50, 0xB1, 0xF1, 0x3A, 0xA8, 0x3D, 0xFD, 0x80, 0xD1, 0xF9,
|
||||||
|
0xB8, 0x05, 0x22, 0xAF, 0xC8, 0x35, 0x45, 0x90, 0x58, 0x8E, 0xE3, 0x3A, 0x7C, 0xBD, 0x3E,
|
||||||
|
0x27};
|
||||||
// p
|
// p
|
||||||
const CryptoPP::byte* Prime1;
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xFE, 0xF6, 0xBF, 0x1D, 0x69, 0xAB, 0x16, 0x25, 0x08, 0x47, 0x55, 0x6B, 0x86, 0xE4, 0x35,
|
||||||
|
0x88, 0x72, 0x2A, 0xB1, 0x3D, 0xF8, 0xB6, 0x44, 0xCA, 0xB3, 0xAB, 0x19, 0xD1, 0x04, 0x24,
|
||||||
|
0x28, 0x0A, 0x74, 0x55, 0xB8, 0x15, 0x45, 0x09, 0xCC, 0x13, 0x1C, 0xF2, 0xBA, 0x37, 0xA9,
|
||||||
|
0x03, 0x90, 0x8F, 0x02, 0x10, 0xFF, 0x25, 0x79, 0x86, 0xCC, 0x18, 0x50, 0x9A, 0x10, 0x5F,
|
||||||
|
0x5B, 0x4C, 0x1C, 0x4E, 0xB0, 0xA7, 0xE3, 0x59, 0xB1, 0x2D, 0xA0, 0xC6, 0xB0, 0x20, 0x2C,
|
||||||
|
0x21, 0x33, 0x12, 0xB3, 0xAF, 0x72, 0x34, 0x83, 0xCD, 0x52, 0x2F, 0xAF, 0x0F, 0x20, 0x5A,
|
||||||
|
0x1B, 0xC0, 0xE2, 0xA3, 0x76, 0x34, 0x0F, 0xD7, 0xFC, 0xC1, 0x41, 0xC9, 0xF9, 0x79, 0x40,
|
||||||
|
0x17, 0x42, 0x21, 0x3E, 0x9D, 0xFD, 0xC7, 0xC1, 0x50, 0xDE, 0x44, 0x5A, 0xC9, 0x31, 0x89,
|
||||||
|
0x6A, 0x78, 0x05, 0xBE, 0x65, 0xB4, 0xE8, 0x2D};
|
||||||
// q
|
// q
|
||||||
const CryptoPP::byte* Prime2;
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
const CryptoPP::byte* PrivateExponent;
|
0xC7, 0x9E, 0x47, 0x58, 0x00, 0x7D, 0x62, 0x82, 0xB0, 0xD2, 0x22, 0x81, 0xD4, 0xA8, 0x97,
|
||||||
|
0x1B, 0x79, 0x0C, 0x3A, 0xB0, 0xD7, 0xC9, 0x30, 0xE3, 0xC3, 0x53, 0x8E, 0x57, 0xEF, 0xF0,
|
||||||
// Constructor
|
0x9B, 0x9F, 0xB3, 0x90, 0x52, 0xC6, 0x94, 0x22, 0x36, 0xAA, 0xE6, 0x4A, 0x5F, 0x72, 0x1D,
|
||||||
FakeKeyset() {
|
0x70, 0xE8, 0x76, 0x58, 0xC8, 0xB2, 0x91, 0xCE, 0x9C, 0xC3, 0xE9, 0x09, 0x7F, 0x2E, 0x47,
|
||||||
// Initialize PrivateExponent
|
0x97, 0xCC, 0x90, 0x39, 0x15, 0x35, 0x31, 0xDE, 0x1F, 0x0C, 0x8C, 0x0D, 0xC1, 0xC2, 0x92,
|
||||||
PrivateExponent = new CryptoPP::byte[0x100]{
|
0xBE, 0x97, 0xBF, 0x2F, 0x91, 0xA1, 0x8C, 0x7D, 0x50, 0xA8, 0x21, 0x2F, 0xD7, 0xA2, 0x9A,
|
||||||
0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D,
|
0x7E, 0xB5, 0xA7, 0x2A, 0x90, 0x02, 0xD9, 0xF3, 0x3D, 0xD1, 0xEB, 0xB8, 0xE0, 0x5A, 0x79,
|
||||||
0xFA, 0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD,
|
0x9E, 0x7D, 0x8D, 0xCA, 0x18, 0x6D, 0xBD, 0x9E, 0xA1, 0x80, 0x28, 0x6B, 0x2A, 0xFE, 0x51,
|
||||||
0xDB, 0xFD, 0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2,
|
0x24, 0x9B, 0x6F, 0x4D, 0x84, 0x77, 0x80, 0x23};
|
||||||
0xB1, 0x22, 0x5C, 0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66,
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
0xD1, 0x49, 0x2C, 0x8F, 0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E,
|
0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D, 0xFA,
|
||||||
0xD2, 0x21, 0x28, 0x83, 0x09, 0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63,
|
0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD, 0xDB, 0xFD,
|
||||||
0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14, 0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8,
|
0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2, 0xB1, 0x22, 0x5C,
|
||||||
0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77, 0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26,
|
0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66, 0xD1, 0x49, 0x2C, 0x8F,
|
||||||
0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90, 0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44,
|
0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E, 0xD2, 0x21, 0x28, 0x83, 0x09,
|
||||||
0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22, 0x58, 0xD5, 0x43, 0x82, 0x49,
|
0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63, 0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14,
|
||||||
0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0, 0xCE, 0x3D, 0xDF, 0xF4,
|
0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8, 0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77,
|
||||||
0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93, 0x23, 0xDB, 0xBA,
|
0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26, 0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90,
|
||||||
0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5, 0x71, 0x67,
|
0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44, 0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22,
|
||||||
0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5, 0x6C,
|
0x58, 0xD5, 0x43, 0x82, 0x49, 0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0,
|
||||||
0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1,
|
0xCE, 0x3D, 0xDF, 0xF4, 0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93,
|
||||||
0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68,
|
0x23, 0xDB, 0xBA, 0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5,
|
||||||
0x85, 0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A,
|
0x71, 0x67, 0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5,
|
||||||
0xEC, 0x39, 0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A,
|
0x6C, 0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1,
|
||||||
0x79, 0x89, 0xC6, 0xB1};
|
0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68, 0x85,
|
||||||
|
0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A, 0xEC, 0x39,
|
||||||
// Initialize Exponent1
|
0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A, 0x79, 0x89, 0xC6,
|
||||||
Exponent1 = new CryptoPP::byte[0x80]{
|
0xB1};
|
||||||
0x6D, 0x48, 0xE0, 0x54, 0x40, 0x25, 0xC8, 0x41, 0x29, 0x52, 0x42, 0x27, 0xEB,
|
|
||||||
0xD2, 0xC7, 0xAB, 0x6B, 0x9C, 0x27, 0x0A, 0xB4, 0x1F, 0x94, 0x4E, 0xFA, 0x42,
|
|
||||||
0x1D, 0xB7, 0xBC, 0xB9, 0xAE, 0xBC, 0x04, 0x6F, 0x75, 0x8F, 0x10, 0x5F, 0x89,
|
|
||||||
0xAC, 0xAB, 0x9C, 0xD2, 0xFA, 0xE6, 0xA4, 0x13, 0x83, 0x68, 0xD4, 0x56, 0x38,
|
|
||||||
0xFE, 0xE5, 0x2B, 0x78, 0x44, 0x9C, 0x34, 0xE6, 0x5A, 0xA0, 0xBE, 0x05, 0x70,
|
|
||||||
0xAD, 0x15, 0xC3, 0x2D, 0x31, 0xAC, 0x97, 0x5D, 0x88, 0xFC, 0xC1, 0x62, 0x3D,
|
|
||||||
0xE2, 0xED, 0x11, 0xDB, 0xB6, 0x9E, 0xFC, 0x5A, 0x5A, 0x03, 0xF6, 0xCF, 0x08,
|
|
||||||
0xD4, 0x5D, 0x90, 0xC9, 0x2A, 0xB9, 0x9B, 0xCF, 0xC8, 0x1A, 0x65, 0xF3, 0x5B,
|
|
||||||
0xE8, 0x7F, 0xCF, 0xA5, 0xA6, 0x4C, 0x5C, 0x2A, 0x12, 0x0F, 0x92, 0xA5, 0xE3,
|
|
||||||
0xF0, 0x17, 0x1E, 0x9A, 0x97, 0x45, 0x86, 0xFD, 0xDB, 0x54, 0x25
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Exponent2 = new CryptoPP::byte[0x80]{
|
|
||||||
0x2A, 0x51, 0xCE, 0x02, 0x44, 0x28, 0x50, 0xE8, 0x30, 0x20, 0x7C, 0x9C, 0x55,
|
|
||||||
0xBF, 0x60, 0x39, 0xBC, 0xD1, 0xF0, 0xE7, 0x68, 0xF8, 0x08, 0x5B, 0x61, 0x1F,
|
|
||||||
0xA7, 0xBF, 0xD0, 0xE8, 0x8B, 0xB5, 0xB1, 0xD5, 0xD9, 0x16, 0xAC, 0x75, 0x0C,
|
|
||||||
0x6D, 0xF2, 0xE0, 0xB5, 0x97, 0x75, 0xD2, 0x68, 0x16, 0x1F, 0x00, 0x7D, 0x8B,
|
|
||||||
0x17, 0xE8, 0x78, 0x48, 0x41, 0x71, 0x2B, 0x18, 0x96, 0x80, 0x11, 0xDB, 0x68,
|
|
||||||
0x39, 0x9C, 0xD6, 0xE0, 0x72, 0x42, 0x86, 0xF0, 0x1B, 0x16, 0x0D, 0x3E, 0x12,
|
|
||||||
0x94, 0x3D, 0x25, 0xA8, 0xA9, 0x30, 0x9E, 0x54, 0x5A, 0xD6, 0x36, 0x6C, 0xD6,
|
|
||||||
0x8C, 0x20, 0x62, 0x8F, 0xA1, 0x6B, 0x1F, 0x7C, 0x6D, 0xB2, 0xB1, 0xC1, 0x2E,
|
|
||||||
0xAD, 0x36, 0x02, 0x9C, 0x3A, 0xCA, 0x2F, 0x09, 0xD2, 0x45, 0x9E, 0xEB, 0xF2,
|
|
||||||
0xBC, 0x6C, 0xAA, 0x3B, 0x3E, 0x90, 0xBC, 0x38, 0x67, 0x35, 0x4D};
|
|
||||||
|
|
||||||
PublicExponent = new CryptoPP::byte[4]{0, 1, 0, 1};
|
|
||||||
|
|
||||||
Coefficient = new CryptoPP::byte[0x80]{
|
|
||||||
0x0B, 0x67, 0x1C, 0x0D, 0x6C, 0x57, 0xD3, 0xE7, 0x05, 0x65, 0x94, 0x31, 0x56,
|
|
||||||
0x55, 0xFD, 0x28, 0x08, 0xFA, 0x05, 0x8A, 0xCC, 0x55, 0x39, 0x61, 0x97, 0x63,
|
|
||||||
0xA0, 0x16, 0x27, 0x3D, 0xED, 0xC1, 0x16, 0x40, 0x2A, 0x12, 0xEA, 0x6F, 0xD9,
|
|
||||||
0xD8, 0x58, 0x56, 0xA8, 0x56, 0x8B, 0x0D, 0x38, 0x5E, 0x1E, 0x80, 0x3B, 0x5F,
|
|
||||||
0x40, 0x80, 0x6F, 0x62, 0x4F, 0x28, 0xA2, 0x69, 0xF3, 0xD3, 0xF7, 0xFD, 0xB2,
|
|
||||||
0xC3, 0x52, 0x43, 0x20, 0x92, 0x9D, 0x97, 0x8D, 0xA0, 0x15, 0x07, 0x15, 0x6E,
|
|
||||||
0xA4, 0x0D, 0x56, 0xD3, 0x37, 0x1A, 0xC4, 0x9E, 0xDF, 0x02, 0x49, 0xB8, 0x0A,
|
|
||||||
0x84, 0x62, 0xF5, 0xFA, 0xB9, 0x3F, 0xA4, 0x09, 0x76, 0xCC, 0xAA, 0xB9, 0x9B,
|
|
||||||
0xA6, 0x4F, 0xC1, 0x6A, 0x64, 0xCE, 0xD8, 0x77, 0xAB, 0x4B, 0xF9, 0xA0, 0xAE,
|
|
||||||
0xDA, 0xF1, 0x67, 0x87, 0x7C, 0x98, 0x5C, 0x7E, 0xB8, 0x73, 0xF5};
|
|
||||||
|
|
||||||
Modulus = new CryptoPP::byte[0x100]{
|
|
||||||
0xC6, 0xCF, 0x71, 0xE7, 0xE5, 0x9A, 0xF0, 0xD1, 0x2A, 0x2C, 0x45, 0x8B, 0xF9, 0x2A,
|
|
||||||
0x0E, 0xC1, 0x43, 0x05, 0x8B, 0xC3, 0x71, 0x17, 0x80, 0x1D, 0xCD, 0x49, 0x7D, 0xDE,
|
|
||||||
0x35, 0x9D, 0x25, 0x9B, 0xA0, 0xD7, 0xA0, 0xF2, 0x7D, 0x6C, 0x08, 0x7E, 0xAA, 0x55,
|
|
||||||
0x02, 0x68, 0x2B, 0x23, 0xC6, 0x44, 0xB8, 0x44, 0x18, 0xEB, 0x56, 0xCF, 0x16, 0xA2,
|
|
||||||
0x48, 0x03, 0xC9, 0xE7, 0x4F, 0x87, 0xEB, 0x3D, 0x30, 0xC3, 0x15, 0x88, 0xBF, 0x20,
|
|
||||||
0xE7, 0x9D, 0xFF, 0x77, 0x0C, 0xDE, 0x1D, 0x24, 0x1E, 0x63, 0xA9, 0x4F, 0x8A, 0xBF,
|
|
||||||
0x5B, 0xBE, 0x60, 0x19, 0x68, 0x33, 0x3B, 0xFC, 0xED, 0x9F, 0x47, 0x4E, 0x5F, 0xF8,
|
|
||||||
0xEA, 0xCB, 0x3D, 0x00, 0xBD, 0x67, 0x01, 0xF9, 0x2C, 0x6D, 0xC6, 0xAC, 0x13, 0x64,
|
|
||||||
0xE7, 0x67, 0x14, 0xF3, 0xDC, 0x52, 0x69, 0x6A, 0xB9, 0x83, 0x2C, 0x42, 0x30, 0x13,
|
|
||||||
0x1B, 0xB2, 0xD8, 0xA5, 0x02, 0x0D, 0x79, 0xED, 0x96, 0xB1, 0x0D, 0xF8, 0xCC, 0x0C,
|
|
||||||
0xDF, 0x81, 0x95, 0x4F, 0x03, 0x58, 0x09, 0x57, 0x0E, 0x80, 0x69, 0x2E, 0xFE, 0xFF,
|
|
||||||
0x52, 0x77, 0xEA, 0x75, 0x28, 0xA8, 0xFB, 0xC9, 0xBE, 0xBF, 0x9F, 0xBB, 0xB7, 0x79,
|
|
||||||
0x8E, 0x18, 0x05, 0xE1, 0x80, 0xBD, 0x50, 0x34, 0x94, 0x81, 0xD3, 0x53, 0xC2, 0x69,
|
|
||||||
0xA2, 0xD2, 0x4C, 0xCF, 0x6C, 0xF4, 0x57, 0x2C, 0x10, 0x4A, 0x3F, 0xFB, 0x22, 0xFD,
|
|
||||||
0x8B, 0x97, 0xE2, 0xC9, 0x5B, 0xA6, 0x2B, 0xCD, 0xD6, 0x1B, 0x6B, 0xDB, 0x68, 0x7F,
|
|
||||||
0x4B, 0xC2, 0xA0, 0x50, 0x34, 0xC0, 0x05, 0xE5, 0x8D, 0xEF, 0x24, 0x67, 0xFF, 0x93,
|
|
||||||
0x40, 0xCF, 0x2D, 0x62, 0xA2, 0xA0, 0x50, 0xB1, 0xF1, 0x3A, 0xA8, 0x3D, 0xFD, 0x80,
|
|
||||||
0xD1, 0xF9, 0xB8, 0x05, 0x22, 0xAF, 0xC8, 0x35, 0x45, 0x90, 0x58, 0x8E, 0xE3, 0x3A,
|
|
||||||
0x7C, 0xBD, 0x3E, 0x27};
|
|
||||||
|
|
||||||
Prime1 = new CryptoPP::byte[0x80]{
|
|
||||||
0xFE, 0xF6, 0xBF, 0x1D, 0x69, 0xAB, 0x16, 0x25, 0x08, 0x47, 0x55, 0x6B, 0x86,
|
|
||||||
0xE4, 0x35, 0x88, 0x72, 0x2A, 0xB1, 0x3D, 0xF8, 0xB6, 0x44, 0xCA, 0xB3, 0xAB,
|
|
||||||
0x19, 0xD1, 0x04, 0x24, 0x28, 0x0A, 0x74, 0x55, 0xB8, 0x15, 0x45, 0x09, 0xCC,
|
|
||||||
0x13, 0x1C, 0xF2, 0xBA, 0x37, 0xA9, 0x03, 0x90, 0x8F, 0x02, 0x10, 0xFF, 0x25,
|
|
||||||
0x79, 0x86, 0xCC, 0x18, 0x50, 0x9A, 0x10, 0x5F, 0x5B, 0x4C, 0x1C, 0x4E, 0xB0,
|
|
||||||
0xA7, 0xE3, 0x59, 0xB1, 0x2D, 0xA0, 0xC6, 0xB0, 0x20, 0x2C, 0x21, 0x33, 0x12,
|
|
||||||
0xB3, 0xAF, 0x72, 0x34, 0x83, 0xCD, 0x52, 0x2F, 0xAF, 0x0F, 0x20, 0x5A, 0x1B,
|
|
||||||
0xC0, 0xE2, 0xA3, 0x76, 0x34, 0x0F, 0xD7, 0xFC, 0xC1, 0x41, 0xC9, 0xF9, 0x79,
|
|
||||||
0x40, 0x17, 0x42, 0x21, 0x3E, 0x9D, 0xFD, 0xC7, 0xC1, 0x50, 0xDE, 0x44, 0x5A,
|
|
||||||
0xC9, 0x31, 0x89, 0x6A, 0x78, 0x05, 0xBE, 0x65, 0xB4, 0xE8, 0x2D};
|
|
||||||
|
|
||||||
Prime2 = new CryptoPP::byte[0x80]{
|
|
||||||
0xC7, 0x9E, 0x47, 0x58, 0x00, 0x7D, 0x62, 0x82, 0xB0, 0xD2, 0x22, 0x81, 0xD4,
|
|
||||||
0xA8, 0x97, 0x1B, 0x79, 0x0C, 0x3A, 0xB0, 0xD7, 0xC9, 0x30, 0xE3, 0xC3, 0x53,
|
|
||||||
0x8E, 0x57, 0xEF, 0xF0, 0x9B, 0x9F, 0xB3, 0x90, 0x52, 0xC6, 0x94, 0x22, 0x36,
|
|
||||||
0xAA, 0xE6, 0x4A, 0x5F, 0x72, 0x1D, 0x70, 0xE8, 0x76, 0x58, 0xC8, 0xB2, 0x91,
|
|
||||||
0xCE, 0x9C, 0xC3, 0xE9, 0x09, 0x7F, 0x2E, 0x47, 0x97, 0xCC, 0x90, 0x39, 0x15,
|
|
||||||
0x35, 0x31, 0xDE, 0x1F, 0x0C, 0x8C, 0x0D, 0xC1, 0xC2, 0x92, 0xBE, 0x97, 0xBF,
|
|
||||||
0x2F, 0x91, 0xA1, 0x8C, 0x7D, 0x50, 0xA8, 0x21, 0x2F, 0xD7, 0xA2, 0x9A, 0x7E,
|
|
||||||
0xB5, 0xA7, 0x2A, 0x90, 0x02, 0xD9, 0xF3, 0x3D, 0xD1, 0xEB, 0xB8, 0xE0, 0x5A,
|
|
||||||
0x79, 0x9E, 0x7D, 0x8D, 0xCA, 0x18, 0x6D, 0xBD, 0x9E, 0xA1, 0x80, 0x28, 0x6B,
|
|
||||||
0x2A, 0xFE, 0x51, 0x24, 0x9B, 0x6F, 0x4D, 0x84, 0x77, 0x80, 0x23};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebugRifKeyset {
|
class DebugRifKeyset {
|
||||||
public:
|
public:
|
||||||
// Constructor
|
|
||||||
// std::uint8_t* PrivateExponent;
|
// std::uint8_t* PrivateExponent;
|
||||||
const CryptoPP::byte* Exponent1;
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0xCD, 0x9A, 0x61, 0xB0, 0xB8, 0xD5, 0xB4, 0xE4, 0xE4, 0xF6, 0xAB, 0xF7, 0x27, 0xB7, 0x56,
|
||||||
|
0x59, 0x6B, 0xB9, 0x11, 0xE7, 0xF4, 0x83, 0xAF, 0xB9, 0x73, 0x99, 0x7F, 0x49, 0xA2, 0x9C,
|
||||||
|
0xF0, 0xB5, 0x6D, 0x37, 0x82, 0x14, 0x15, 0xF1, 0x04, 0x8A, 0xD4, 0x8E, 0xEB, 0x2E, 0x1F,
|
||||||
|
0xE2, 0x81, 0xA9, 0x62, 0x6E, 0xB1, 0x68, 0x75, 0x62, 0xF3, 0x0F, 0xFE, 0xD4, 0x91, 0x87,
|
||||||
|
0x98, 0x78, 0xBF, 0x26, 0xB5, 0x07, 0x58, 0xD0, 0xEE, 0x3F, 0x21, 0xE8, 0xC8, 0x0F, 0x5F,
|
||||||
|
0xFA, 0x1C, 0x64, 0x74, 0x49, 0x52, 0xEB, 0xE7, 0xEE, 0xDE, 0xBA, 0x23, 0x26, 0x4A, 0xF6,
|
||||||
|
0x9C, 0x1A, 0x09, 0x3F, 0xB9, 0x0B, 0x36, 0x26, 0x1A, 0xBE, 0xA9, 0x76, 0xE6, 0xF2, 0x69,
|
||||||
|
0xDE, 0xFF, 0xAF, 0xCC, 0x0C, 0x9A, 0x66, 0x03, 0x86, 0x0A, 0x1F, 0x49, 0xA4, 0x10, 0xB6,
|
||||||
|
0xBC, 0xC3, 0x7C, 0x88, 0xE8, 0xCE, 0x4B, 0xD9};
|
||||||
// exponent2 = d mod (q - 1)
|
// exponent2 = d mod (q - 1)
|
||||||
const CryptoPP::byte* Exponent2;
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0xB3, 0x73, 0xA3, 0x59, 0xE6, 0x97, 0xC0, 0xAB, 0x3B, 0x68, 0xFC, 0x39, 0xAC, 0xDB, 0x44,
|
||||||
|
0xB1, 0xB4, 0x9E, 0x35, 0x4D, 0xBE, 0xC5, 0x36, 0x69, 0x6C, 0x3D, 0xC5, 0xFC, 0xFE, 0x4B,
|
||||||
|
0x2F, 0xDC, 0x86, 0x80, 0x46, 0x96, 0x40, 0x1A, 0x0D, 0x6E, 0xFA, 0x8C, 0xE0, 0x47, 0x91,
|
||||||
|
0xAC, 0xAD, 0x95, 0x2B, 0x8E, 0x1F, 0xF2, 0x0A, 0x45, 0xF8, 0x29, 0x95, 0x70, 0xC6, 0x88,
|
||||||
|
0x5F, 0x71, 0x03, 0x99, 0x79, 0xBC, 0x84, 0x71, 0xBD, 0xE8, 0x84, 0x8C, 0x0E, 0xD4, 0x7B,
|
||||||
|
0x30, 0x74, 0x57, 0x1A, 0x95, 0xE7, 0x90, 0x19, 0x8D, 0xAD, 0x8B, 0x4C, 0x4E, 0xC3, 0xE7,
|
||||||
|
0x6B, 0x23, 0x86, 0x01, 0xEE, 0x9B, 0xE0, 0x2F, 0x15, 0xA2, 0x2C, 0x4C, 0x39, 0xD3, 0xDF,
|
||||||
|
0x9C, 0x39, 0x01, 0xF1, 0x8C, 0x44, 0x4A, 0x15, 0x44, 0xDC, 0x51, 0xF7, 0x22, 0xD7, 0x7F,
|
||||||
|
0x41, 0x7F, 0x68, 0xFA, 0xEE, 0x56, 0xE8, 0x05};
|
||||||
// e
|
// e
|
||||||
const CryptoPP::byte* PublicExponent;
|
static constexpr CryptoPP::byte PublicExponent[] = {0x00, 0x01, 0x00, 0x01};
|
||||||
// (InverseQ)(q) = 1 mod p
|
// (InverseQ)(q) = 1 mod p
|
||||||
const CryptoPP::byte* Coefficient;
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0xC0, 0x32, 0x43, 0xD3, 0x8C, 0x3D, 0xB4, 0xD2, 0x48, 0x8C, 0x42, 0x41, 0x24, 0x94, 0x6C,
|
||||||
|
0x80, 0xC9, 0xC1, 0x79, 0x36, 0x7F, 0xAC, 0xC3, 0xFF, 0x6A, 0x25, 0xEB, 0x2C, 0xFB, 0xD4,
|
||||||
|
0x2B, 0xA0, 0xEB, 0xFE, 0x25, 0xE9, 0xC6, 0x77, 0xCE, 0xFE, 0x2D, 0x23, 0xFE, 0xD0, 0xF4,
|
||||||
|
0x0F, 0xD9, 0x7E, 0xD5, 0xA5, 0x7D, 0x1F, 0xC0, 0xE8, 0xE8, 0xEC, 0x80, 0x5B, 0xC7, 0xFD,
|
||||||
|
0xE2, 0xBD, 0x94, 0xA6, 0x2B, 0xDD, 0x6A, 0x60, 0x45, 0x54, 0xAB, 0xCA, 0x42, 0x9C, 0x6A,
|
||||||
|
0x6C, 0xBF, 0x3C, 0x84, 0xF9, 0xA5, 0x0E, 0x63, 0x0C, 0x51, 0x58, 0x62, 0x6D, 0x5A, 0xB7,
|
||||||
|
0x3C, 0x3F, 0x49, 0x1A, 0xD0, 0x93, 0xB8, 0x4F, 0x1A, 0x6C, 0x5F, 0xC5, 0xE5, 0xA9, 0x75,
|
||||||
|
0xD4, 0x86, 0x9E, 0xDF, 0x87, 0x0F, 0x27, 0xB0, 0x26, 0x78, 0x4E, 0xFB, 0xC1, 0x8A, 0x4A,
|
||||||
|
0x24, 0x3F, 0x7F, 0x8F, 0x9A, 0x12, 0x51, 0xCB};
|
||||||
// n = p * q
|
// n = p * q
|
||||||
const CryptoPP::byte* Modulus;
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xC2, 0xD2, 0x44, 0xBC, 0xDD, 0x84, 0x3F, 0xD9, 0xC5, 0x22, 0xAF, 0xF7, 0xFC, 0x88, 0x8A,
|
||||||
|
0x33, 0x80, 0xED, 0x8E, 0xE2, 0xCC, 0x81, 0xF7, 0xEC, 0xF8, 0x1C, 0x79, 0xBF, 0x02, 0xBB,
|
||||||
|
0x12, 0x8E, 0x61, 0x68, 0x29, 0x1B, 0x15, 0xB6, 0x5E, 0xC6, 0xF8, 0xBF, 0x5A, 0xE0, 0x3B,
|
||||||
|
0x6A, 0x6C, 0xD9, 0xD6, 0xF5, 0x75, 0xAB, 0xA0, 0x6F, 0x34, 0x81, 0x34, 0x9A, 0x5B, 0xAD,
|
||||||
|
0xED, 0x31, 0xE3, 0xC6, 0xEA, 0x1A, 0xD1, 0x13, 0x22, 0xBB, 0xB3, 0xDA, 0xB3, 0xB2, 0x53,
|
||||||
|
0xBD, 0x45, 0x79, 0x87, 0xAD, 0x0A, 0x01, 0x72, 0x18, 0x10, 0x29, 0x49, 0xF4, 0x41, 0x7F,
|
||||||
|
0xD6, 0x47, 0x0C, 0x72, 0x92, 0x9E, 0xE9, 0xBB, 0x95, 0xA9, 0x5D, 0x79, 0xEB, 0xE4, 0x30,
|
||||||
|
0x76, 0x90, 0x45, 0x4B, 0x9D, 0x9C, 0xCF, 0x92, 0x03, 0x60, 0x8C, 0x4B, 0x6C, 0xB3, 0x7A,
|
||||||
|
0x3A, 0x05, 0x39, 0xA0, 0x66, 0xA9, 0x35, 0xCF, 0xB9, 0xFA, 0xAD, 0x9C, 0xAB, 0xEB, 0xE4,
|
||||||
|
0x6A, 0x8C, 0xE9, 0x3B, 0xCC, 0x72, 0x12, 0x62, 0x63, 0xBD, 0x80, 0xC4, 0xEE, 0x37, 0x2B,
|
||||||
|
0x32, 0x03, 0xA3, 0x09, 0xF7, 0xA0, 0x61, 0x57, 0xAD, 0x0D, 0xCF, 0x15, 0x98, 0x9E, 0x4E,
|
||||||
|
0x49, 0xF8, 0xB5, 0xA3, 0x5C, 0x27, 0xEE, 0x45, 0x04, 0xEA, 0xE4, 0x4B, 0xBC, 0x8F, 0x87,
|
||||||
|
0xED, 0x19, 0x1E, 0x46, 0x75, 0x63, 0xC4, 0x5B, 0xD5, 0xBC, 0x09, 0x2F, 0x02, 0x73, 0x19,
|
||||||
|
0x3C, 0x58, 0x55, 0x49, 0x66, 0x4C, 0x11, 0xEC, 0x0F, 0x09, 0xFA, 0xA5, 0x56, 0x0A, 0x5A,
|
||||||
|
0x63, 0x56, 0xAD, 0xA0, 0x0D, 0x86, 0x08, 0xC1, 0xE6, 0xB6, 0x13, 0x22, 0x49, 0x2F, 0x7C,
|
||||||
|
0xDB, 0x4C, 0x56, 0x97, 0x0E, 0xC2, 0xD9, 0x2E, 0x87, 0xBC, 0x0E, 0x67, 0xC0, 0x1B, 0x58,
|
||||||
|
0xBC, 0x64, 0x2B, 0xC2, 0x6E, 0xE2, 0x93, 0x2E, 0xB5, 0x6B, 0x70, 0xA4, 0x42, 0x9F, 0x64,
|
||||||
|
0xC1};
|
||||||
// p
|
// p
|
||||||
const CryptoPP::byte* Prime1;
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xE5, 0x62, 0xE1, 0x7F, 0x9F, 0x86, 0x08, 0xE2, 0x61, 0xD3, 0xD0, 0x42, 0xE2, 0xC4, 0xB6,
|
||||||
|
0xA8, 0x51, 0x09, 0x19, 0x14, 0xA4, 0x3A, 0x11, 0x4C, 0x33, 0xA5, 0x9C, 0x01, 0x5E, 0x34,
|
||||||
|
0xB6, 0x3F, 0x02, 0x1A, 0xCA, 0x47, 0xF1, 0x4F, 0x3B, 0x35, 0x2A, 0x07, 0x20, 0xEC, 0xD8,
|
||||||
|
0xC1, 0x15, 0xD9, 0xCA, 0x03, 0x4F, 0xB8, 0xE8, 0x09, 0x73, 0x3F, 0x85, 0xB7, 0x41, 0xD5,
|
||||||
|
0x51, 0x3E, 0x7B, 0xE3, 0x53, 0x2B, 0x48, 0x8B, 0x8E, 0xCB, 0xBA, 0xF7, 0xE0, 0x60, 0xF5,
|
||||||
|
0x35, 0x0E, 0x6F, 0xB0, 0xD9, 0x2A, 0x99, 0xD0, 0xFF, 0x60, 0x14, 0xED, 0x40, 0xEA, 0xF8,
|
||||||
|
0xD7, 0x0B, 0xC3, 0x8D, 0x8C, 0xE8, 0x81, 0xB3, 0x75, 0x93, 0x15, 0xB3, 0x7D, 0xF6, 0x39,
|
||||||
|
0x60, 0x1A, 0x00, 0xE7, 0xC3, 0x27, 0xAD, 0xA4, 0x33, 0xD5, 0x3E, 0xA4, 0x35, 0x48, 0x6F,
|
||||||
|
0x22, 0xEF, 0x5D, 0xDD, 0x7D, 0x7B, 0x61, 0x05};
|
||||||
// q
|
// q
|
||||||
const CryptoPP::byte* Prime2;
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
const CryptoPP::byte* PrivateExponent;
|
0xD9, 0x6C, 0xC2, 0x0C, 0xF7, 0xAE, 0xD1, 0xF3, 0x3B, 0x3B, 0x49, 0x1E, 0x9F, 0x12, 0x9C,
|
||||||
|
0xA1, 0x78, 0x1F, 0x35, 0x1D, 0x98, 0x26, 0x13, 0x71, 0xF9, 0x09, 0xFD, 0xF0, 0xAD, 0x38,
|
||||||
// Constructor
|
0x55, 0xB7, 0xEE, 0x61, 0x04, 0x72, 0x51, 0x87, 0x2E, 0x05, 0x84, 0xB1, 0x1D, 0x0C, 0x0D,
|
||||||
DebugRifKeyset() {
|
0xDB, 0xD4, 0x25, 0x3E, 0x26, 0xED, 0xEA, 0xB8, 0xF7, 0x49, 0xFE, 0xA2, 0x94, 0xE6, 0xF2,
|
||||||
// Initialize PrivateExponent
|
0x08, 0x92, 0xA7, 0x85, 0xF5, 0x30, 0xB9, 0x84, 0x22, 0xBF, 0xCA, 0xF0, 0x5F, 0xCB, 0x31,
|
||||||
PrivateExponent = new CryptoPP::byte[0x100]{
|
0x20, 0x34, 0x49, 0x16, 0x76, 0x34, 0xCC, 0x7A, 0xCB, 0x96, 0xFE, 0x78, 0x7A, 0x41, 0xFE,
|
||||||
0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83,
|
0x9A, 0xA2, 0x23, 0xF7, 0x68, 0x80, 0xD6, 0xCE, 0x4A, 0x78, 0xA5, 0xB7, 0x05, 0x77, 0x81,
|
||||||
0x01, 0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97,
|
0x1F, 0xDE, 0x5E, 0xA8, 0x6E, 0x3E, 0x87, 0xEC, 0x44, 0xD2, 0x69, 0xC6, 0x54, 0x91, 0x6B,
|
||||||
0x64, 0xEC, 0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0,
|
0x5E, 0x13, 0x8A, 0x03, 0x87, 0x05, 0x31, 0x8D};
|
||||||
0xC6, 0xA3, 0x73, 0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8,
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
0x23, 0xD8, 0x1B, 0x61, 0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8,
|
0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83, 0x01,
|
||||||
0x03, 0x4A, 0xBF, 0xFE, 0xF9, 0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F,
|
0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97, 0x64, 0xEC,
|
||||||
0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28, 0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF,
|
0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0, 0xC6, 0xA3, 0x73,
|
||||||
0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36, 0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC,
|
0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8, 0x23, 0xD8, 0x1B, 0x61,
|
||||||
0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E, 0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC,
|
0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8, 0x03, 0x4A, 0xBF, 0xFE, 0xF9,
|
||||||
0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14, 0x3D, 0x90, 0xE4, 0xDE, 0x5D,
|
0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F, 0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28,
|
||||||
0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97, 0x2D, 0x89, 0x2A, 0x51,
|
0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF, 0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36,
|
||||||
0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F, 0xA1, 0x8A, 0x69,
|
0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC, 0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E,
|
||||||
0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C, 0xC7, 0xE8,
|
0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC, 0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14,
|
||||||
0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61, 0xB9,
|
0x3D, 0x90, 0xE4, 0xDE, 0x5D, 0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97,
|
||||||
0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49,
|
0x2D, 0x89, 0x2A, 0x51, 0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F,
|
||||||
0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC,
|
0xA1, 0x8A, 0x69, 0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C,
|
||||||
0xB3, 0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4,
|
0xC7, 0xE8, 0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61,
|
||||||
0xAF, 0x6E, 0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3,
|
0xB9, 0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49,
|
||||||
0xF1, 0xCF, 0x14, 0xA5};
|
0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC, 0xB3,
|
||||||
|
0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4, 0xAF, 0x6E,
|
||||||
// Initialize Exponent1
|
0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3, 0xF1, 0xCF, 0x14,
|
||||||
Exponent1 = new CryptoPP::byte[0x80]{
|
0xA5};
|
||||||
0xCD, 0x9A, 0x61, 0xB0, 0xB8, 0xD5, 0xB4, 0xE4, 0xE4, 0xF6, 0xAB, 0xF7, 0x27,
|
|
||||||
0xB7, 0x56, 0x59, 0x6B, 0xB9, 0x11, 0xE7, 0xF4, 0x83, 0xAF, 0xB9, 0x73, 0x99,
|
|
||||||
0x7F, 0x49, 0xA2, 0x9C, 0xF0, 0xB5, 0x6D, 0x37, 0x82, 0x14, 0x15, 0xF1, 0x04,
|
|
||||||
0x8A, 0xD4, 0x8E, 0xEB, 0x2E, 0x1F, 0xE2, 0x81, 0xA9, 0x62, 0x6E, 0xB1, 0x68,
|
|
||||||
0x75, 0x62, 0xF3, 0x0F, 0xFE, 0xD4, 0x91, 0x87, 0x98, 0x78, 0xBF, 0x26, 0xB5,
|
|
||||||
0x07, 0x58, 0xD0, 0xEE, 0x3F, 0x21, 0xE8, 0xC8, 0x0F, 0x5F, 0xFA, 0x1C, 0x64,
|
|
||||||
0x74, 0x49, 0x52, 0xEB, 0xE7, 0xEE, 0xDE, 0xBA, 0x23, 0x26, 0x4A, 0xF6, 0x9C,
|
|
||||||
0x1A, 0x09, 0x3F, 0xB9, 0x0B, 0x36, 0x26, 0x1A, 0xBE, 0xA9, 0x76, 0xE6, 0xF2,
|
|
||||||
0x69, 0xDE, 0xFF, 0xAF, 0xCC, 0x0C, 0x9A, 0x66, 0x03, 0x86, 0x0A, 0x1F, 0x49,
|
|
||||||
0xA4, 0x10, 0xB6, 0xBC, 0xC3, 0x7C, 0x88, 0xE8, 0xCE, 0x4B, 0xD9
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Exponent2 = new CryptoPP::byte[0x80]{
|
|
||||||
0xB3, 0x73, 0xA3, 0x59, 0xE6, 0x97, 0xC0, 0xAB, 0x3B, 0x68, 0xFC, 0x39, 0xAC,
|
|
||||||
0xDB, 0x44, 0xB1, 0xB4, 0x9E, 0x35, 0x4D, 0xBE, 0xC5, 0x36, 0x69, 0x6C, 0x3D,
|
|
||||||
0xC5, 0xFC, 0xFE, 0x4B, 0x2F, 0xDC, 0x86, 0x80, 0x46, 0x96, 0x40, 0x1A, 0x0D,
|
|
||||||
0x6E, 0xFA, 0x8C, 0xE0, 0x47, 0x91, 0xAC, 0xAD, 0x95, 0x2B, 0x8E, 0x1F, 0xF2,
|
|
||||||
0x0A, 0x45, 0xF8, 0x29, 0x95, 0x70, 0xC6, 0x88, 0x5F, 0x71, 0x03, 0x99, 0x79,
|
|
||||||
0xBC, 0x84, 0x71, 0xBD, 0xE8, 0x84, 0x8C, 0x0E, 0xD4, 0x7B, 0x30, 0x74, 0x57,
|
|
||||||
0x1A, 0x95, 0xE7, 0x90, 0x19, 0x8D, 0xAD, 0x8B, 0x4C, 0x4E, 0xC3, 0xE7, 0x6B,
|
|
||||||
0x23, 0x86, 0x01, 0xEE, 0x9B, 0xE0, 0x2F, 0x15, 0xA2, 0x2C, 0x4C, 0x39, 0xD3,
|
|
||||||
0xDF, 0x9C, 0x39, 0x01, 0xF1, 0x8C, 0x44, 0x4A, 0x15, 0x44, 0xDC, 0x51, 0xF7,
|
|
||||||
0x22, 0xD7, 0x7F, 0x41, 0x7F, 0x68, 0xFA, 0xEE, 0x56, 0xE8, 0x05};
|
|
||||||
|
|
||||||
PublicExponent = new CryptoPP::byte[4]{0x00, 0x01, 0x00, 0x01};
|
|
||||||
|
|
||||||
Coefficient = new CryptoPP::byte[0x80]{
|
|
||||||
0xC0, 0x32, 0x43, 0xD3, 0x8C, 0x3D, 0xB4, 0xD2, 0x48, 0x8C, 0x42, 0x41, 0x24,
|
|
||||||
0x94, 0x6C, 0x80, 0xC9, 0xC1, 0x79, 0x36, 0x7F, 0xAC, 0xC3, 0xFF, 0x6A, 0x25,
|
|
||||||
0xEB, 0x2C, 0xFB, 0xD4, 0x2B, 0xA0, 0xEB, 0xFE, 0x25, 0xE9, 0xC6, 0x77, 0xCE,
|
|
||||||
0xFE, 0x2D, 0x23, 0xFE, 0xD0, 0xF4, 0x0F, 0xD9, 0x7E, 0xD5, 0xA5, 0x7D, 0x1F,
|
|
||||||
0xC0, 0xE8, 0xE8, 0xEC, 0x80, 0x5B, 0xC7, 0xFD, 0xE2, 0xBD, 0x94, 0xA6, 0x2B,
|
|
||||||
0xDD, 0x6A, 0x60, 0x45, 0x54, 0xAB, 0xCA, 0x42, 0x9C, 0x6A, 0x6C, 0xBF, 0x3C,
|
|
||||||
0x84, 0xF9, 0xA5, 0x0E, 0x63, 0x0C, 0x51, 0x58, 0x62, 0x6D, 0x5A, 0xB7, 0x3C,
|
|
||||||
0x3F, 0x49, 0x1A, 0xD0, 0x93, 0xB8, 0x4F, 0x1A, 0x6C, 0x5F, 0xC5, 0xE5, 0xA9,
|
|
||||||
0x75, 0xD4, 0x86, 0x9E, 0xDF, 0x87, 0x0F, 0x27, 0xB0, 0x26, 0x78, 0x4E, 0xFB,
|
|
||||||
0xC1, 0x8A, 0x4A, 0x24, 0x3F, 0x7F, 0x8F, 0x9A, 0x12, 0x51, 0xCB};
|
|
||||||
|
|
||||||
Modulus = new CryptoPP::byte[0x100]{
|
|
||||||
0xC2, 0xD2, 0x44, 0xBC, 0xDD, 0x84, 0x3F, 0xD9, 0xC5, 0x22, 0xAF, 0xF7, 0xFC, 0x88,
|
|
||||||
0x8A, 0x33, 0x80, 0xED, 0x8E, 0xE2, 0xCC, 0x81, 0xF7, 0xEC, 0xF8, 0x1C, 0x79, 0xBF,
|
|
||||||
0x02, 0xBB, 0x12, 0x8E, 0x61, 0x68, 0x29, 0x1B, 0x15, 0xB6, 0x5E, 0xC6, 0xF8, 0xBF,
|
|
||||||
0x5A, 0xE0, 0x3B, 0x6A, 0x6C, 0xD9, 0xD6, 0xF5, 0x75, 0xAB, 0xA0, 0x6F, 0x34, 0x81,
|
|
||||||
0x34, 0x9A, 0x5B, 0xAD, 0xED, 0x31, 0xE3, 0xC6, 0xEA, 0x1A, 0xD1, 0x13, 0x22, 0xBB,
|
|
||||||
0xB3, 0xDA, 0xB3, 0xB2, 0x53, 0xBD, 0x45, 0x79, 0x87, 0xAD, 0x0A, 0x01, 0x72, 0x18,
|
|
||||||
0x10, 0x29, 0x49, 0xF4, 0x41, 0x7F, 0xD6, 0x47, 0x0C, 0x72, 0x92, 0x9E, 0xE9, 0xBB,
|
|
||||||
0x95, 0xA9, 0x5D, 0x79, 0xEB, 0xE4, 0x30, 0x76, 0x90, 0x45, 0x4B, 0x9D, 0x9C, 0xCF,
|
|
||||||
0x92, 0x03, 0x60, 0x8C, 0x4B, 0x6C, 0xB3, 0x7A, 0x3A, 0x05, 0x39, 0xA0, 0x66, 0xA9,
|
|
||||||
0x35, 0xCF, 0xB9, 0xFA, 0xAD, 0x9C, 0xAB, 0xEB, 0xE4, 0x6A, 0x8C, 0xE9, 0x3B, 0xCC,
|
|
||||||
0x72, 0x12, 0x62, 0x63, 0xBD, 0x80, 0xC4, 0xEE, 0x37, 0x2B, 0x32, 0x03, 0xA3, 0x09,
|
|
||||||
0xF7, 0xA0, 0x61, 0x57, 0xAD, 0x0D, 0xCF, 0x15, 0x98, 0x9E, 0x4E, 0x49, 0xF8, 0xB5,
|
|
||||||
0xA3, 0x5C, 0x27, 0xEE, 0x45, 0x04, 0xEA, 0xE4, 0x4B, 0xBC, 0x8F, 0x87, 0xED, 0x19,
|
|
||||||
0x1E, 0x46, 0x75, 0x63, 0xC4, 0x5B, 0xD5, 0xBC, 0x09, 0x2F, 0x02, 0x73, 0x19, 0x3C,
|
|
||||||
0x58, 0x55, 0x49, 0x66, 0x4C, 0x11, 0xEC, 0x0F, 0x09, 0xFA, 0xA5, 0x56, 0x0A, 0x5A,
|
|
||||||
0x63, 0x56, 0xAD, 0xA0, 0x0D, 0x86, 0x08, 0xC1, 0xE6, 0xB6, 0x13, 0x22, 0x49, 0x2F,
|
|
||||||
0x7C, 0xDB, 0x4C, 0x56, 0x97, 0x0E, 0xC2, 0xD9, 0x2E, 0x87, 0xBC, 0x0E, 0x67, 0xC0,
|
|
||||||
0x1B, 0x58, 0xBC, 0x64, 0x2B, 0xC2, 0x6E, 0xE2, 0x93, 0x2E, 0xB5, 0x6B, 0x70, 0xA4,
|
|
||||||
0x42, 0x9F, 0x64, 0xC1};
|
|
||||||
|
|
||||||
Prime1 = new CryptoPP::byte[0x80]{
|
|
||||||
0xE5, 0x62, 0xE1, 0x7F, 0x9F, 0x86, 0x08, 0xE2, 0x61, 0xD3, 0xD0, 0x42, 0xE2,
|
|
||||||
0xC4, 0xB6, 0xA8, 0x51, 0x09, 0x19, 0x14, 0xA4, 0x3A, 0x11, 0x4C, 0x33, 0xA5,
|
|
||||||
0x9C, 0x01, 0x5E, 0x34, 0xB6, 0x3F, 0x02, 0x1A, 0xCA, 0x47, 0xF1, 0x4F, 0x3B,
|
|
||||||
0x35, 0x2A, 0x07, 0x20, 0xEC, 0xD8, 0xC1, 0x15, 0xD9, 0xCA, 0x03, 0x4F, 0xB8,
|
|
||||||
0xE8, 0x09, 0x73, 0x3F, 0x85, 0xB7, 0x41, 0xD5, 0x51, 0x3E, 0x7B, 0xE3, 0x53,
|
|
||||||
0x2B, 0x48, 0x8B, 0x8E, 0xCB, 0xBA, 0xF7, 0xE0, 0x60, 0xF5, 0x35, 0x0E, 0x6F,
|
|
||||||
0xB0, 0xD9, 0x2A, 0x99, 0xD0, 0xFF, 0x60, 0x14, 0xED, 0x40, 0xEA, 0xF8, 0xD7,
|
|
||||||
0x0B, 0xC3, 0x8D, 0x8C, 0xE8, 0x81, 0xB3, 0x75, 0x93, 0x15, 0xB3, 0x7D, 0xF6,
|
|
||||||
0x39, 0x60, 0x1A, 0x00, 0xE7, 0xC3, 0x27, 0xAD, 0xA4, 0x33, 0xD5, 0x3E, 0xA4,
|
|
||||||
0x35, 0x48, 0x6F, 0x22, 0xEF, 0x5D, 0xDD, 0x7D, 0x7B, 0x61, 0x05};
|
|
||||||
|
|
||||||
Prime2 = new CryptoPP::byte[0x80]{
|
|
||||||
0xD9, 0x6C, 0xC2, 0x0C, 0xF7, 0xAE, 0xD1, 0xF3, 0x3B, 0x3B, 0x49, 0x1E, 0x9F,
|
|
||||||
0x12, 0x9C, 0xA1, 0x78, 0x1F, 0x35, 0x1D, 0x98, 0x26, 0x13, 0x71, 0xF9, 0x09,
|
|
||||||
0xFD, 0xF0, 0xAD, 0x38, 0x55, 0xB7, 0xEE, 0x61, 0x04, 0x72, 0x51, 0x87, 0x2E,
|
|
||||||
0x05, 0x84, 0xB1, 0x1D, 0x0C, 0x0D, 0xDB, 0xD4, 0x25, 0x3E, 0x26, 0xED, 0xEA,
|
|
||||||
0xB8, 0xF7, 0x49, 0xFE, 0xA2, 0x94, 0xE6, 0xF2, 0x08, 0x92, 0xA7, 0x85, 0xF5,
|
|
||||||
0x30, 0xB9, 0x84, 0x22, 0xBF, 0xCA, 0xF0, 0x5F, 0xCB, 0x31, 0x20, 0x34, 0x49,
|
|
||||||
0x16, 0x76, 0x34, 0xCC, 0x7A, 0xCB, 0x96, 0xFE, 0x78, 0x7A, 0x41, 0xFE, 0x9A,
|
|
||||||
0xA2, 0x23, 0xF7, 0x68, 0x80, 0xD6, 0xCE, 0x4A, 0x78, 0xA5, 0xB7, 0x05, 0x77,
|
|
||||||
0x81, 0x1F, 0xDE, 0x5E, 0xA8, 0x6E, 0x3E, 0x87, 0xEC, 0x44, 0xD2, 0x69, 0xC6,
|
|
||||||
0x54, 0x91, 0x6B, 0x5E, 0x13, 0x8A, 0x03, 0x87, 0x05, 0x31, 0x8D};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PkgDerivedKey3Keyset {
|
class PkgDerivedKey3Keyset {
|
||||||
public:
|
public:
|
||||||
// PkgDerivedKey3Keyset();
|
|
||||||
//~PkgDerivedKey3Keyset();
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
// std::uint8_t* PrivateExponent;
|
// std::uint8_t* PrivateExponent;
|
||||||
const CryptoPP::byte* Exponent1;
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0x52, 0xCC, 0x2D, 0xA0, 0x9C, 0x9E, 0x75, 0xE7, 0x28, 0xEE, 0x3D, 0xDE, 0xE3, 0x45, 0xD1,
|
||||||
|
0x4F, 0x94, 0x1C, 0xCC, 0xC8, 0x87, 0x29, 0x45, 0x3B, 0x8D, 0x6E, 0xAB, 0x6E, 0x2A, 0xA7,
|
||||||
|
0xC7, 0x15, 0x43, 0xA3, 0x04, 0x8F, 0x90, 0x5F, 0xEB, 0xF3, 0x38, 0x4A, 0x77, 0xFA, 0x36,
|
||||||
|
0xB7, 0x15, 0x76, 0xB6, 0x01, 0x1A, 0x8E, 0x25, 0x87, 0x82, 0xF1, 0x55, 0xD8, 0xC6, 0x43,
|
||||||
|
0x2A, 0xC0, 0xE5, 0x98, 0xC9, 0x32, 0xD1, 0x94, 0x6F, 0xD9, 0x01, 0xBA, 0x06, 0x81, 0xE0,
|
||||||
|
0x6D, 0x88, 0xF2, 0x24, 0x2A, 0x25, 0x01, 0x64, 0x5C, 0xBF, 0xF2, 0xD9, 0x99, 0x67, 0x3E,
|
||||||
|
0xF6, 0x72, 0xEE, 0xE4, 0xE2, 0x33, 0x5C, 0xF8, 0x00, 0x40, 0xE3, 0x2A, 0x9A, 0xF4, 0x3D,
|
||||||
|
0x22, 0x86, 0x44, 0x3C, 0xFB, 0x0A, 0xA5, 0x7C, 0x3F, 0xCC, 0xF5, 0xF1, 0x16, 0xC4, 0xAC,
|
||||||
|
0x88, 0xB4, 0xDE, 0x62, 0x94, 0x92, 0x6A, 0x13};
|
||||||
// exponent2 = d mod (q - 1)
|
// exponent2 = d mod (q - 1)
|
||||||
const CryptoPP::byte* Exponent2;
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0x7C, 0x9D, 0xAD, 0x39, 0xE0, 0xD5, 0x60, 0x14, 0x94, 0x48, 0x19, 0x7F, 0x88, 0x95, 0xD5,
|
||||||
|
0x8B, 0x80, 0xAD, 0x85, 0x8A, 0x4B, 0x77, 0x37, 0x85, 0xD0, 0x77, 0xBB, 0xBF, 0x89, 0x71,
|
||||||
|
0x4A, 0x72, 0xCB, 0x72, 0x68, 0x38, 0xEC, 0x02, 0xC6, 0x7D, 0xC6, 0x44, 0x06, 0x33, 0x51,
|
||||||
|
0x1C, 0xC0, 0xFF, 0x95, 0x8F, 0x0D, 0x75, 0xDC, 0x25, 0xBB, 0x0B, 0x73, 0x91, 0xA9, 0x6D,
|
||||||
|
0x42, 0xD8, 0x03, 0xB7, 0x68, 0xD4, 0x1E, 0x75, 0x62, 0xA3, 0x70, 0x35, 0x79, 0x78, 0x00,
|
||||||
|
0xC8, 0xF5, 0xEF, 0x15, 0xB9, 0xFC, 0x4E, 0x47, 0x5A, 0xC8, 0x70, 0x70, 0x5B, 0x52, 0x98,
|
||||||
|
0xC0, 0xC2, 0x58, 0x4A, 0x70, 0x96, 0xCC, 0xB8, 0x10, 0xE1, 0x2F, 0x78, 0x8B, 0x2B, 0xA1,
|
||||||
|
0x7F, 0xF9, 0xAC, 0xDE, 0xF0, 0xBB, 0x2B, 0xE2, 0x66, 0xE3, 0x22, 0x92, 0x31, 0x21, 0x57,
|
||||||
|
0x92, 0xC4, 0xB8, 0xF2, 0x3E, 0x76, 0x20, 0x37};
|
||||||
// e
|
// e
|
||||||
const CryptoPP::byte* PublicExponent;
|
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||||
// (InverseQ)(q) = 1 mod p
|
// (InverseQ)(q) = 1 mod p
|
||||||
const CryptoPP::byte* Coefficient;
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0x45, 0x97, 0x55, 0xD4, 0x22, 0x08, 0x5E, 0xF3, 0x5C, 0xB4, 0x05, 0x7A, 0xFD, 0xAA, 0x42,
|
||||||
|
0x42, 0xAD, 0x9A, 0x8C, 0xA0, 0x6C, 0xBB, 0x1D, 0x68, 0x54, 0x54, 0x6E, 0x3E, 0x32, 0xE3,
|
||||||
|
0x53, 0x73, 0x76, 0xF1, 0x3E, 0x01, 0xEA, 0xD3, 0xCF, 0xEB, 0xEB, 0x23, 0x3E, 0xC0, 0xBE,
|
||||||
|
0xCE, 0xEC, 0x2C, 0x89, 0x5F, 0xA8, 0x27, 0x3A, 0x4C, 0xB7, 0xE6, 0x74, 0xBC, 0x45, 0x4C,
|
||||||
|
0x26, 0xC8, 0x25, 0xFF, 0x34, 0x63, 0x25, 0x37, 0xE1, 0x48, 0x10, 0xC1, 0x93, 0xA6, 0xAF,
|
||||||
|
0xEB, 0xBA, 0xE3, 0xA2, 0xF1, 0x3D, 0xEF, 0x63, 0xD8, 0xF4, 0xFD, 0xD3, 0xEE, 0xE2, 0x5D,
|
||||||
|
0xE9, 0x33, 0xCC, 0xAD, 0xBA, 0x75, 0x5C, 0x85, 0xAF, 0xCE, 0xA9, 0x3D, 0xD1, 0xA2, 0x17,
|
||||||
|
0xF3, 0xF6, 0x98, 0xB3, 0x50, 0x8E, 0x5E, 0xF6, 0xEB, 0x02, 0x8E, 0xA1, 0x62, 0xA7, 0xD6,
|
||||||
|
0x2C, 0xEC, 0x91, 0xFF, 0x15, 0x40, 0xD2, 0xE3};
|
||||||
// n = p * q
|
// n = p * q
|
||||||
const CryptoPP::byte* Modulus;
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xd2, 0x12, 0xfc, 0x33, 0x5f, 0x6d, 0xdb, 0x83, 0x16, 0x09, 0x62, 0x8b, 0x03, 0x56, 0x27,
|
||||||
|
0x37, 0x82, 0xd4, 0x77, 0x85, 0x35, 0x29, 0x39, 0x2d, 0x52, 0x6b, 0x8c, 0x4c, 0x8c, 0xfb,
|
||||||
|
0x06, 0xc1, 0x84, 0x5b, 0xe7, 0xd4, 0xf7, 0xbc, 0xd2, 0x4e, 0x62, 0x45, 0xcd, 0x2a, 0xbb,
|
||||||
|
0xd7, 0x77, 0x76, 0x45, 0x36, 0x55, 0x27, 0x3f, 0xb3, 0xf5, 0xf9, 0x8e, 0xda, 0x4b, 0xef,
|
||||||
|
0xaa, 0x59, 0xae, 0xb3, 0x9b, 0xea, 0x54, 0x98, 0xd2, 0x06, 0x32, 0x6a, 0x58, 0x31, 0x2a,
|
||||||
|
0xe0, 0xd4, 0x4f, 0x90, 0xb5, 0x0a, 0x7d, 0xec, 0xf4, 0x3a, 0x9c, 0x52, 0x67, 0x2d, 0x99,
|
||||||
|
0x31, 0x8e, 0x0c, 0x43, 0xe6, 0x82, 0xfe, 0x07, 0x46, 0xe1, 0x2e, 0x50, 0xd4, 0x1f, 0x2d,
|
||||||
|
0x2f, 0x7e, 0xd9, 0x08, 0xba, 0x06, 0xb3, 0xbf, 0x2e, 0x20, 0x3f, 0x4e, 0x3f, 0xfe, 0x44,
|
||||||
|
0xff, 0xaa, 0x50, 0x43, 0x57, 0x91, 0x69, 0x94, 0x49, 0x15, 0x82, 0x82, 0xe4, 0x0f, 0x4c,
|
||||||
|
0x8d, 0x9d, 0x2c, 0xc9, 0x5b, 0x1d, 0x64, 0xbf, 0x88, 0x8b, 0xd4, 0xc5, 0x94, 0xe7, 0x65,
|
||||||
|
0x47, 0x84, 0x1e, 0xe5, 0x79, 0x10, 0xfb, 0x98, 0x93, 0x47, 0xb9, 0x7d, 0x85, 0x12, 0xa6,
|
||||||
|
0x40, 0x98, 0x2c, 0xf7, 0x92, 0xbc, 0x95, 0x19, 0x32, 0xed, 0xe8, 0x90, 0x56, 0x0d, 0x65,
|
||||||
|
0xc1, 0xaa, 0x78, 0xc6, 0x2e, 0x54, 0xfd, 0x5f, 0x54, 0xa1, 0xf6, 0x7e, 0xe5, 0xe0, 0x5f,
|
||||||
|
0x61, 0xc1, 0x20, 0xb4, 0xb9, 0xb4, 0x33, 0x08, 0x70, 0xe4, 0xdf, 0x89, 0x56, 0xed, 0x01,
|
||||||
|
0x29, 0x46, 0x77, 0x5f, 0x8c, 0xb8, 0xa9, 0xf5, 0x1e, 0x2e, 0xb3, 0xb9, 0xbf, 0xe0, 0x09,
|
||||||
|
0xb7, 0x8d, 0x28, 0xd4, 0xa6, 0xc3, 0xb8, 0x1e, 0x1f, 0x07, 0xeb, 0xb4, 0x12, 0x0b, 0x95,
|
||||||
|
0xb8, 0x85, 0x30, 0xfd, 0xdc, 0x39, 0x13, 0xd0, 0x7c, 0xdc, 0x8f, 0xed, 0xf9, 0xc9, 0xa3,
|
||||||
|
0xc1};
|
||||||
// p
|
// p
|
||||||
const CryptoPP::byte* Prime1;
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xF9, 0x67, 0xAD, 0x99, 0x12, 0x31, 0x0C, 0x56, 0xA2, 0x2E, 0x16, 0x1C, 0x46, 0xB3, 0x4D,
|
||||||
|
0x5B, 0x43, 0xBE, 0x42, 0xA2, 0xF6, 0x86, 0x96, 0x80, 0x42, 0xC3, 0xC7, 0x3F, 0xC3, 0x42,
|
||||||
|
0xF5, 0x87, 0x49, 0x33, 0x9F, 0x07, 0x5D, 0x6E, 0x2C, 0x04, 0xFD, 0xE3, 0xE1, 0xB2, 0xAE,
|
||||||
|
0x0A, 0x0C, 0xF0, 0xC7, 0xA6, 0x1C, 0xA1, 0x63, 0x50, 0xC8, 0x09, 0x9C, 0x51, 0x24, 0x52,
|
||||||
|
0x6C, 0x5E, 0x5E, 0xBD, 0x1E, 0x27, 0x06, 0xBB, 0xBC, 0x9E, 0x94, 0xE1, 0x35, 0xD4, 0x6D,
|
||||||
|
0xB3, 0xCB, 0x3C, 0x68, 0xDD, 0x68, 0xB3, 0xFE, 0x6C, 0xCB, 0x8D, 0x82, 0x20, 0x76, 0x23,
|
||||||
|
0x63, 0xB7, 0xE9, 0x68, 0x10, 0x01, 0x4E, 0xDC, 0xBA, 0x27, 0x5D, 0x01, 0xC1, 0x2D, 0x80,
|
||||||
|
0x5E, 0x2B, 0xAF, 0x82, 0x6B, 0xD8, 0x84, 0xB6, 0x10, 0x52, 0x86, 0xA7, 0x89, 0x8E, 0xAE,
|
||||||
|
0x9A, 0xE2, 0x89, 0xC6, 0xF7, 0xD5, 0x87, 0xFB};
|
||||||
// q
|
// q
|
||||||
const CryptoPP::byte* Prime2;
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
const CryptoPP::byte* PrivateExponent;
|
0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0, 0xD9, 0x40,
|
||||||
|
0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65, 0xF9, 0xC3, 0x61, 0x0F,
|
||||||
PkgDerivedKey3Keyset() {
|
0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40, 0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89,
|
||||||
|
0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F, 0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9,
|
||||||
Prime1 = new CryptoPP::byte[0x80]{
|
0xB4, 0xC7, 0xB5, 0x1B, 0x05, 0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E,
|
||||||
0xF9, 0x67, 0xAD, 0x99, 0x12, 0x31, 0x0C, 0x56, 0xA2, 0x2E, 0x16, 0x1C, 0x46,
|
0x5C, 0xFB, 0x92, 0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C,
|
||||||
0xB3, 0x4D, 0x5B, 0x43, 0xBE, 0x42, 0xA2, 0xF6, 0x86, 0x96, 0x80, 0x42, 0xC3,
|
0x07, 0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5, 0x53,
|
||||||
0xC7, 0x3F, 0xC3, 0x42, 0xF5, 0x87, 0x49, 0x33, 0x9F, 0x07, 0x5D, 0x6E, 0x2C,
|
0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92, 0x01, 0xEE, 0x10,
|
||||||
0x04, 0xFD, 0xE3, 0xE1, 0xB2, 0xAE, 0x0A, 0x0C, 0xF0, 0xC7, 0xA6, 0x1C, 0xA1,
|
0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73};
|
||||||
0x63, 0x50, 0xC8, 0x09, 0x9C, 0x51, 0x24, 0x52, 0x6C, 0x5E, 0x5E, 0xBD, 0x1E,
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
0x27, 0x06, 0xBB, 0xBC, 0x9E, 0x94, 0xE1, 0x35, 0xD4, 0x6D, 0xB3, 0xCB, 0x3C,
|
0x32, 0xD9, 0x03, 0x90, 0x8F, 0xBD, 0xB0, 0x8F, 0x57, 0x2B, 0x28, 0x5E, 0x0B, 0x8D, 0xB3,
|
||||||
0x68, 0xDD, 0x68, 0xB3, 0xFE, 0x6C, 0xCB, 0x8D, 0x82, 0x20, 0x76, 0x23, 0x63,
|
0xEA, 0x5C, 0xD1, 0x7E, 0xA8, 0x90, 0x88, 0x8C, 0xDD, 0x6A, 0x80, 0xBB, 0xB1, 0xDF, 0xC1,
|
||||||
0xB7, 0xE9, 0x68, 0x10, 0x01, 0x4E, 0xDC, 0xBA, 0x27, 0x5D, 0x01, 0xC1, 0x2D,
|
0xF7, 0x0D, 0xAA, 0x32, 0xF0, 0xB7, 0x7C, 0xCB, 0x88, 0x80, 0x0E, 0x8B, 0x64, 0xB0, 0xBE,
|
||||||
0x80, 0x5E, 0x2B, 0xAF, 0x82, 0x6B, 0xD8, 0x84, 0xB6, 0x10, 0x52, 0x86, 0xA7,
|
0x4C, 0xD6, 0x0E, 0x9B, 0x8C, 0x1E, 0x2A, 0x64, 0xE1, 0xF3, 0x5C, 0xD7, 0x76, 0x01, 0x41,
|
||||||
0x89, 0x8E, 0xAE, 0x9A, 0xE2, 0x89, 0xC6, 0xF7, 0xD5, 0x87, 0xFB};
|
0x5E, 0x93, 0x5C, 0x94, 0xFE, 0xDD, 0x46, 0x62, 0xC3, 0x1B, 0x5A, 0xE2, 0xA0, 0xBC, 0x2D,
|
||||||
|
0xEB, 0xC3, 0x98, 0x0A, 0xA7, 0xB7, 0x85, 0x69, 0x70, 0x68, 0x2B, 0x64, 0x4A, 0xB3, 0x1F,
|
||||||
Prime2 = new CryptoPP::byte[0x80]{
|
0xCC, 0x7D, 0xDC, 0x7C, 0x26, 0xF4, 0x77, 0xF6, 0x5C, 0xF2, 0xAE, 0x5A, 0x44, 0x2D, 0xD3,
|
||||||
0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0,
|
0xAB, 0x16, 0x62, 0x04, 0x19, 0xBA, 0xFB, 0x90, 0xFF, 0xE2, 0x30, 0x50, 0x89, 0x6E, 0xCB,
|
||||||
0xD9, 0x40, 0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65,
|
0x56, 0xB2, 0xEB, 0xC0, 0x91, 0x16, 0x92, 0x5E, 0x30, 0x8E, 0xAE, 0xC7, 0x94, 0x5D, 0xFD,
|
||||||
0xF9, 0xC3, 0x61, 0x0F, 0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40,
|
0x35, 0xE1, 0x20, 0xF8, 0xAD, 0x3E, 0xBC, 0x08, 0xBF, 0xC0, 0x36, 0x74, 0x9F, 0xD5, 0xBB,
|
||||||
0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89, 0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F,
|
0x52, 0x08, 0xFD, 0x06, 0x66, 0xF3, 0x7A, 0xB3, 0x04, 0xF4, 0x75, 0x29, 0x5D, 0xE9, 0x5F,
|
||||||
0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9, 0xB4, 0xC7, 0xB5, 0x1B, 0x05,
|
0xAA, 0x10, 0x30, 0xB2, 0x0F, 0x5A, 0x1A, 0xC1, 0x2A, 0xB3, 0xFE, 0xCB, 0x21, 0xAD, 0x80,
|
||||||
0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E, 0x5C, 0xFB, 0x92,
|
0xEC, 0x8F, 0x20, 0x09, 0x1C, 0xDB, 0xC5, 0x58, 0x94, 0xC2, 0x9C, 0xC6, 0xCE, 0x82, 0x65,
|
||||||
0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C, 0x07,
|
0x3E, 0x57, 0x90, 0xBC, 0xA9, 0x8B, 0x06, 0xB4, 0xF0, 0x72, 0xF6, 0x77, 0xDF, 0x98, 0x64,
|
||||||
0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5,
|
0xF1, 0xEC, 0xFE, 0x37, 0x2D, 0xBC, 0xAE, 0x8C, 0x08, 0x81, 0x1F, 0xC3, 0xC9, 0x89, 0x1A,
|
||||||
0x53, 0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92,
|
0xC7, 0x42, 0x82, 0x4B, 0x2E, 0xDC, 0x8E, 0x8D, 0x73, 0xCE, 0xB1, 0xCC, 0x01, 0xD9, 0x08,
|
||||||
0x01, 0xEE, 0x10, 0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73};
|
0x70, 0x87, 0x3C, 0x44, 0x08, 0xEC, 0x49, 0x8F, 0x81, 0x5A, 0xE2, 0x40, 0xFF, 0x77, 0xFC,
|
||||||
PrivateExponent = new CryptoPP::byte[0x100]{
|
0x0D};
|
||||||
0x32, 0xD9, 0x03, 0x90, 0x8F, 0xBD, 0xB0, 0x8F, 0x57, 0x2B, 0x28, 0x5E, 0x0B, 0x8D,
|
|
||||||
0xB3, 0xEA, 0x5C, 0xD1, 0x7E, 0xA8, 0x90, 0x88, 0x8C, 0xDD, 0x6A, 0x80, 0xBB, 0xB1,
|
|
||||||
0xDF, 0xC1, 0xF7, 0x0D, 0xAA, 0x32, 0xF0, 0xB7, 0x7C, 0xCB, 0x88, 0x80, 0x0E, 0x8B,
|
|
||||||
0x64, 0xB0, 0xBE, 0x4C, 0xD6, 0x0E, 0x9B, 0x8C, 0x1E, 0x2A, 0x64, 0xE1, 0xF3, 0x5C,
|
|
||||||
0xD7, 0x76, 0x01, 0x41, 0x5E, 0x93, 0x5C, 0x94, 0xFE, 0xDD, 0x46, 0x62, 0xC3, 0x1B,
|
|
||||||
0x5A, 0xE2, 0xA0, 0xBC, 0x2D, 0xEB, 0xC3, 0x98, 0x0A, 0xA7, 0xB7, 0x85, 0x69, 0x70,
|
|
||||||
0x68, 0x2B, 0x64, 0x4A, 0xB3, 0x1F, 0xCC, 0x7D, 0xDC, 0x7C, 0x26, 0xF4, 0x77, 0xF6,
|
|
||||||
0x5C, 0xF2, 0xAE, 0x5A, 0x44, 0x2D, 0xD3, 0xAB, 0x16, 0x62, 0x04, 0x19, 0xBA, 0xFB,
|
|
||||||
0x90, 0xFF, 0xE2, 0x30, 0x50, 0x89, 0x6E, 0xCB, 0x56, 0xB2, 0xEB, 0xC0, 0x91, 0x16,
|
|
||||||
0x92, 0x5E, 0x30, 0x8E, 0xAE, 0xC7, 0x94, 0x5D, 0xFD, 0x35, 0xE1, 0x20, 0xF8, 0xAD,
|
|
||||||
0x3E, 0xBC, 0x08, 0xBF, 0xC0, 0x36, 0x74, 0x9F, 0xD5, 0xBB, 0x52, 0x08, 0xFD, 0x06,
|
|
||||||
0x66, 0xF3, 0x7A, 0xB3, 0x04, 0xF4, 0x75, 0x29, 0x5D, 0xE9, 0x5F, 0xAA, 0x10, 0x30,
|
|
||||||
0xB2, 0x0F, 0x5A, 0x1A, 0xC1, 0x2A, 0xB3, 0xFE, 0xCB, 0x21, 0xAD, 0x80, 0xEC, 0x8F,
|
|
||||||
0x20, 0x09, 0x1C, 0xDB, 0xC5, 0x58, 0x94, 0xC2, 0x9C, 0xC6, 0xCE, 0x82, 0x65, 0x3E,
|
|
||||||
0x57, 0x90, 0xBC, 0xA9, 0x8B, 0x06, 0xB4, 0xF0, 0x72, 0xF6, 0x77, 0xDF, 0x98, 0x64,
|
|
||||||
0xF1, 0xEC, 0xFE, 0x37, 0x2D, 0xBC, 0xAE, 0x8C, 0x08, 0x81, 0x1F, 0xC3, 0xC9, 0x89,
|
|
||||||
0x1A, 0xC7, 0x42, 0x82, 0x4B, 0x2E, 0xDC, 0x8E, 0x8D, 0x73, 0xCE, 0xB1, 0xCC, 0x01,
|
|
||||||
0xD9, 0x08, 0x70, 0x87, 0x3C, 0x44, 0x08, 0xEC, 0x49, 0x8F, 0x81, 0x5A, 0xE2, 0x40,
|
|
||||||
0xFF, 0x77, 0xFC, 0x0D};
|
|
||||||
Exponent1 = new CryptoPP::byte[0x80]{
|
|
||||||
0x52, 0xCC, 0x2D, 0xA0, 0x9C, 0x9E, 0x75, 0xE7, 0x28, 0xEE, 0x3D, 0xDE, 0xE3,
|
|
||||||
0x45, 0xD1, 0x4F, 0x94, 0x1C, 0xCC, 0xC8, 0x87, 0x29, 0x45, 0x3B, 0x8D, 0x6E,
|
|
||||||
0xAB, 0x6E, 0x2A, 0xA7, 0xC7, 0x15, 0x43, 0xA3, 0x04, 0x8F, 0x90, 0x5F, 0xEB,
|
|
||||||
0xF3, 0x38, 0x4A, 0x77, 0xFA, 0x36, 0xB7, 0x15, 0x76, 0xB6, 0x01, 0x1A, 0x8E,
|
|
||||||
0x25, 0x87, 0x82, 0xF1, 0x55, 0xD8, 0xC6, 0x43, 0x2A, 0xC0, 0xE5, 0x98, 0xC9,
|
|
||||||
0x32, 0xD1, 0x94, 0x6F, 0xD9, 0x01, 0xBA, 0x06, 0x81, 0xE0, 0x6D, 0x88, 0xF2,
|
|
||||||
0x24, 0x2A, 0x25, 0x01, 0x64, 0x5C, 0xBF, 0xF2, 0xD9, 0x99, 0x67, 0x3E, 0xF6,
|
|
||||||
0x72, 0xEE, 0xE4, 0xE2, 0x33, 0x5C, 0xF8, 0x00, 0x40, 0xE3, 0x2A, 0x9A, 0xF4,
|
|
||||||
0x3D, 0x22, 0x86, 0x44, 0x3C, 0xFB, 0x0A, 0xA5, 0x7C, 0x3F, 0xCC, 0xF5, 0xF1,
|
|
||||||
0x16, 0xC4, 0xAC, 0x88, 0xB4, 0xDE, 0x62, 0x94, 0x92, 0x6A, 0x13};
|
|
||||||
Exponent2 = new CryptoPP::byte[0x80]{
|
|
||||||
0x7C, 0x9D, 0xAD, 0x39, 0xE0, 0xD5, 0x60, 0x14, 0x94, 0x48, 0x19, 0x7F, 0x88,
|
|
||||||
0x95, 0xD5, 0x8B, 0x80, 0xAD, 0x85, 0x8A, 0x4B, 0x77, 0x37, 0x85, 0xD0, 0x77,
|
|
||||||
0xBB, 0xBF, 0x89, 0x71, 0x4A, 0x72, 0xCB, 0x72, 0x68, 0x38, 0xEC, 0x02, 0xC6,
|
|
||||||
0x7D, 0xC6, 0x44, 0x06, 0x33, 0x51, 0x1C, 0xC0, 0xFF, 0x95, 0x8F, 0x0D, 0x75,
|
|
||||||
0xDC, 0x25, 0xBB, 0x0B, 0x73, 0x91, 0xA9, 0x6D, 0x42, 0xD8, 0x03, 0xB7, 0x68,
|
|
||||||
0xD4, 0x1E, 0x75, 0x62, 0xA3, 0x70, 0x35, 0x79, 0x78, 0x00, 0xC8, 0xF5, 0xEF,
|
|
||||||
0x15, 0xB9, 0xFC, 0x4E, 0x47, 0x5A, 0xC8, 0x70, 0x70, 0x5B, 0x52, 0x98, 0xC0,
|
|
||||||
0xC2, 0x58, 0x4A, 0x70, 0x96, 0xCC, 0xB8, 0x10, 0xE1, 0x2F, 0x78, 0x8B, 0x2B,
|
|
||||||
0xA1, 0x7F, 0xF9, 0xAC, 0xDE, 0xF0, 0xBB, 0x2B, 0xE2, 0x66, 0xE3, 0x22, 0x92,
|
|
||||||
0x31, 0x21, 0x57, 0x92, 0xC4, 0xB8, 0xF2, 0x3E, 0x76, 0x20, 0x37};
|
|
||||||
Coefficient = new CryptoPP::byte[0x80]{
|
|
||||||
0x45, 0x97, 0x55, 0xD4, 0x22, 0x08, 0x5E, 0xF3, 0x5C, 0xB4, 0x05, 0x7A, 0xFD,
|
|
||||||
0xAA, 0x42, 0x42, 0xAD, 0x9A, 0x8C, 0xA0, 0x6C, 0xBB, 0x1D, 0x68, 0x54, 0x54,
|
|
||||||
0x6E, 0x3E, 0x32, 0xE3, 0x53, 0x73, 0x76, 0xF1, 0x3E, 0x01, 0xEA, 0xD3, 0xCF,
|
|
||||||
0xEB, 0xEB, 0x23, 0x3E, 0xC0, 0xBE, 0xCE, 0xEC, 0x2C, 0x89, 0x5F, 0xA8, 0x27,
|
|
||||||
0x3A, 0x4C, 0xB7, 0xE6, 0x74, 0xBC, 0x45, 0x4C, 0x26, 0xC8, 0x25, 0xFF, 0x34,
|
|
||||||
0x63, 0x25, 0x37, 0xE1, 0x48, 0x10, 0xC1, 0x93, 0xA6, 0xAF, 0xEB, 0xBA, 0xE3,
|
|
||||||
0xA2, 0xF1, 0x3D, 0xEF, 0x63, 0xD8, 0xF4, 0xFD, 0xD3, 0xEE, 0xE2, 0x5D, 0xE9,
|
|
||||||
0x33, 0xCC, 0xAD, 0xBA, 0x75, 0x5C, 0x85, 0xAF, 0xCE, 0xA9, 0x3D, 0xD1, 0xA2,
|
|
||||||
0x17, 0xF3, 0xF6, 0x98, 0xB3, 0x50, 0x8E, 0x5E, 0xF6, 0xEB, 0x02, 0x8E, 0xA1,
|
|
||||||
0x62, 0xA7, 0xD6, 0x2C, 0xEC, 0x91, 0xFF, 0x15, 0x40, 0xD2, 0xE3};
|
|
||||||
Modulus = new CryptoPP::byte[0x100]{
|
|
||||||
0xd2, 0x12, 0xfc, 0x33, 0x5f, 0x6d, 0xdb, 0x83, 0x16, 0x09, 0x62, 0x8b, 0x03, 0x56,
|
|
||||||
0x27, 0x37, 0x82, 0xd4, 0x77, 0x85, 0x35, 0x29, 0x39, 0x2d, 0x52, 0x6b, 0x8c, 0x4c,
|
|
||||||
0x8c, 0xfb, 0x06, 0xc1, 0x84, 0x5b, 0xe7, 0xd4, 0xf7, 0xbc, 0xd2, 0x4e, 0x62, 0x45,
|
|
||||||
0xcd, 0x2a, 0xbb, 0xd7, 0x77, 0x76, 0x45, 0x36, 0x55, 0x27, 0x3f, 0xb3, 0xf5, 0xf9,
|
|
||||||
0x8e, 0xda, 0x4b, 0xef, 0xaa, 0x59, 0xae, 0xb3, 0x9b, 0xea, 0x54, 0x98, 0xd2, 0x06,
|
|
||||||
0x32, 0x6a, 0x58, 0x31, 0x2a, 0xe0, 0xd4, 0x4f, 0x90, 0xb5, 0x0a, 0x7d, 0xec, 0xf4,
|
|
||||||
0x3a, 0x9c, 0x52, 0x67, 0x2d, 0x99, 0x31, 0x8e, 0x0c, 0x43, 0xe6, 0x82, 0xfe, 0x07,
|
|
||||||
0x46, 0xe1, 0x2e, 0x50, 0xd4, 0x1f, 0x2d, 0x2f, 0x7e, 0xd9, 0x08, 0xba, 0x06, 0xb3,
|
|
||||||
0xbf, 0x2e, 0x20, 0x3f, 0x4e, 0x3f, 0xfe, 0x44, 0xff, 0xaa, 0x50, 0x43, 0x57, 0x91,
|
|
||||||
0x69, 0x94, 0x49, 0x15, 0x82, 0x82, 0xe4, 0x0f, 0x4c, 0x8d, 0x9d, 0x2c, 0xc9, 0x5b,
|
|
||||||
0x1d, 0x64, 0xbf, 0x88, 0x8b, 0xd4, 0xc5, 0x94, 0xe7, 0x65, 0x47, 0x84, 0x1e, 0xe5,
|
|
||||||
0x79, 0x10, 0xfb, 0x98, 0x93, 0x47, 0xb9, 0x7d, 0x85, 0x12, 0xa6, 0x40, 0x98, 0x2c,
|
|
||||||
0xf7, 0x92, 0xbc, 0x95, 0x19, 0x32, 0xed, 0xe8, 0x90, 0x56, 0x0d, 0x65, 0xc1, 0xaa,
|
|
||||||
0x78, 0xc6, 0x2e, 0x54, 0xfd, 0x5f, 0x54, 0xa1, 0xf6, 0x7e, 0xe5, 0xe0, 0x5f, 0x61,
|
|
||||||
0xc1, 0x20, 0xb4, 0xb9, 0xb4, 0x33, 0x08, 0x70, 0xe4, 0xdf, 0x89, 0x56, 0xed, 0x01,
|
|
||||||
0x29, 0x46, 0x77, 0x5f, 0x8c, 0xb8, 0xa9, 0xf5, 0x1e, 0x2e, 0xb3, 0xb9, 0xbf, 0xe0,
|
|
||||||
0x09, 0xb7, 0x8d, 0x28, 0xd4, 0xa6, 0xc3, 0xb8, 0x1e, 0x1f, 0x07, 0xeb, 0xb4, 0x12,
|
|
||||||
0x0b, 0x95, 0xb8, 0x85, 0x30, 0xfd, 0xdc, 0x39, 0x13, 0xd0, 0x7c, 0xdc, 0x8f, 0xed,
|
|
||||||
0xf9, 0xc9, 0xa3, 0xc1};
|
|
||||||
PublicExponent = new CryptoPP::byte[4]{0, 1, 0, 1};
|
|
||||||
};
|
|
||||||
};
|
};
|
|
@ -67,15 +67,19 @@ bool PKG::Open(const std::filesystem::path& filepath) {
|
||||||
file.Seek(0x47); // skip first 7 characters of content_id
|
file.Seek(0x47); // skip first 7 characters of content_id
|
||||||
file.Read(pkgTitleID);
|
file.Read(pkgTitleID);
|
||||||
|
|
||||||
file.Seek(0);
|
|
||||||
pkg.resize(pkgheader.pkg_promote_size);
|
|
||||||
file.Read(pkg);
|
|
||||||
|
|
||||||
u32 offset = pkgheader.pkg_table_entry_offset;
|
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||||
u32 n_files = pkgheader.pkg_table_entry_count;
|
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||||
|
|
||||||
|
file.Seek(offset);
|
||||||
for (int i = 0; i < n_files; i++) {
|
for (int i = 0; i < n_files; i++) {
|
||||||
PKGEntry entry;
|
PKGEntry entry{};
|
||||||
std::memcpy(&entry, &pkg[offset + i * 0x20], sizeof(entry));
|
file.Read(entry.id);
|
||||||
|
file.Read(entry.filename_offset);
|
||||||
|
file.Read(entry.flags1);
|
||||||
|
file.Read(entry.flags2);
|
||||||
|
file.Read(entry.offset);
|
||||||
|
file.Read(entry.size);
|
||||||
|
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||||
|
|
||||||
// Try to figure out the name
|
// Try to figure out the name
|
||||||
const auto name = GetEntryNameByType(entry.id);
|
const auto name = GetEntryNameByType(entry.id);
|
||||||
|
@ -113,9 +117,6 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
failreason = "Content size is bigger than pkg size";
|
failreason = "Content size is bigger than pkg size";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.Seek(0);
|
|
||||||
pkg.resize(pkgheader.pkg_promote_size);
|
|
||||||
file.Read(pkg);
|
|
||||||
|
|
||||||
u32 offset = pkgheader.pkg_table_entry_offset;
|
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||||
u32 n_files = pkgheader.pkg_table_entry_count;
|
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||||
|
@ -126,9 +127,18 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
std::array<std::array<u8, 256>, 7> key1;
|
std::array<std::array<u8, 256>, 7> key1;
|
||||||
std::array<u8, 256> imgkeydata;
|
std::array<u8, 256> imgkeydata;
|
||||||
|
|
||||||
|
file.Seek(offset);
|
||||||
for (int i = 0; i < n_files; i++) {
|
for (int i = 0; i < n_files; i++) {
|
||||||
PKGEntry entry;
|
PKGEntry entry{};
|
||||||
std::memcpy(&entry, &pkg[offset + i * 0x20], sizeof(entry));
|
file.Read(entry.id);
|
||||||
|
file.Read(entry.filename_offset);
|
||||||
|
file.Read(entry.flags1);
|
||||||
|
file.Read(entry.flags2);
|
||||||
|
file.Read(entry.offset);
|
||||||
|
file.Read(entry.size);
|
||||||
|
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||||
|
|
||||||
|
auto currentPos = file.Tell();
|
||||||
|
|
||||||
// Try to figure out the name
|
// Try to figure out the name
|
||||||
const auto name = GetEntryNameByType(entry.id);
|
const auto name = GetEntryNameByType(entry.id);
|
||||||
|
@ -139,8 +149,15 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
// Just print with id
|
// Just print with id
|
||||||
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
|
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
|
||||||
Common::FS::FileAccessMode::Write);
|
Common::FS::FileAccessMode::Write);
|
||||||
out.WriteRaw<u8>(pkg.data() + entry.offset, entry.size);
|
file.Seek(entry.offset);
|
||||||
|
|
||||||
|
std::vector<u8> data;
|
||||||
|
data.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(data.data(), entry.size);
|
||||||
|
out.WriteRaw<u8>(data.data(), entry.size);
|
||||||
out.Close();
|
out.Close();
|
||||||
|
|
||||||
|
file.Seek(currentPos);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,14 +195,25 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
|
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
|
||||||
out.WriteRaw<u8>(pkg.data() + entry.offset, entry.size);
|
file.Seek(entry.offset);
|
||||||
|
|
||||||
|
std::vector<u8> data;
|
||||||
|
data.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(data.data(), entry.size);
|
||||||
|
out.WriteRaw<u8>(data.data(), entry.size);
|
||||||
out.Close();
|
out.Close();
|
||||||
|
|
||||||
// Decrypt Np stuff and overwrite.
|
// Decrypt Np stuff and overwrite.
|
||||||
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
|
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
|
||||||
entry.id == 0x403) { // somehow 0x401 is not decrypting
|
entry.id == 0x403) { // somehow 0x401 is not decrypting
|
||||||
decNp.resize(entry.size);
|
decNp.resize(entry.size);
|
||||||
std::span<u8> cipherNp(pkg.data() + entry.offset, entry.size);
|
file.Seek(entry.offset);
|
||||||
|
|
||||||
|
std::vector<u8> data;
|
||||||
|
data.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(data.data(), entry.size);
|
||||||
|
|
||||||
|
std::span<u8> cipherNp(data.data(), entry.size);
|
||||||
std::array<u8, 64> concatenated_ivkey_dk3_;
|
std::array<u8, 64> concatenated_ivkey_dk3_;
|
||||||
std::memcpy(concatenated_ivkey_dk3_.data(), &entry, sizeof(entry));
|
std::memcpy(concatenated_ivkey_dk3_.data(), &entry, sizeof(entry));
|
||||||
std::memcpy(concatenated_ivkey_dk3_.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
std::memcpy(concatenated_ivkey_dk3_.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
||||||
|
@ -197,6 +225,8 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
out.Write(decNp);
|
out.Write(decNp);
|
||||||
out.Close();
|
out.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.Seek(currentPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract trophy files
|
// Extract trophy files
|
||||||
|
@ -214,6 +244,9 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
PKG::crypto.PfsGenCryptoKey(ekpfsKey, seed, dataKey, tweakKey);
|
PKG::crypto.PfsGenCryptoKey(ekpfsKey, seed, dataKey, tweakKey);
|
||||||
const u32 length = pkgheader.pfs_cache_size * 0x2; // Seems to be ok.
|
const u32 length = pkgheader.pfs_cache_size * 0x2; // Seems to be ok.
|
||||||
|
|
||||||
|
int num_blocks = 0;
|
||||||
|
std::vector<u8> pfsc(length);
|
||||||
|
if (length != 0) {
|
||||||
// Read encrypted pfs_image
|
// Read encrypted pfs_image
|
||||||
std::vector<u8> pfs_encrypted(length);
|
std::vector<u8> pfs_encrypted(length);
|
||||||
file.Seek(pkgheader.pfs_image_offset);
|
file.Seek(pkgheader.pfs_image_offset);
|
||||||
|
@ -225,18 +258,18 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
|
|
||||||
// Retrieve PFSC from decrypted pfs_image.
|
// Retrieve PFSC from decrypted pfs_image.
|
||||||
pfsc_offset = GetPFSCOffset(pfs_decrypted);
|
pfsc_offset = GetPFSCOffset(pfs_decrypted);
|
||||||
std::vector<u8> pfsc(length);
|
|
||||||
std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
|
std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
|
||||||
|
|
||||||
PFSCHdr pfsChdr;
|
PFSCHdr pfsChdr;
|
||||||
std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr));
|
std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr));
|
||||||
|
|
||||||
const int num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2);
|
num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2);
|
||||||
sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset.
|
sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset.
|
||||||
|
|
||||||
for (int i = 0; i < num_blocks + 1; i++) {
|
for (int i = 0; i < num_blocks + 1; i++) {
|
||||||
std::memcpy(§orMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
|
std::memcpy(§orMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 ent_size = 0;
|
u32 ent_size = 0;
|
||||||
u32 ndinode = 0;
|
u32 ndinode = 0;
|
||||||
|
@ -279,8 +312,8 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// let's deal with the root/uroot enteries here.
|
// let's deal with the root/uroot entries here.
|
||||||
// Sometimes it's more than 2 enteries (Tomb Raider Remastered)
|
// Sometimes it's more than 2 entries (Tomb Raider Remastered)
|
||||||
const std::string_view flat_path_table(&decompressedData[0x10], 15);
|
const std::string_view flat_path_table(&decompressedData[0x10], 15);
|
||||||
if (flat_path_table == "flat_path_table") {
|
if (flat_path_table == "flat_path_table") {
|
||||||
uroot_reached = true;
|
uroot_reached = true;
|
||||||
|
@ -296,7 +329,15 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
||||||
} else {
|
} else {
|
||||||
// Set the the folder according to the current inode.
|
// Set the the folder according to the current inode.
|
||||||
// Can be 2 or more (rarely)
|
// Can be 2 or more (rarely)
|
||||||
extractPaths[ndinode_counter] = extract_path.parent_path() / GetTitleID();
|
auto parent_path = extract_path.parent_path();
|
||||||
|
auto title_id = GetTitleID();
|
||||||
|
|
||||||
|
if (parent_path.filename() != title_id) {
|
||||||
|
extractPaths[ndinode_counter] = parent_path / title_id;
|
||||||
|
} else {
|
||||||
|
// DLCs path has different structure
|
||||||
|
extractPaths[ndinode_counter] = extract_path;
|
||||||
|
}
|
||||||
uroot_reached = false;
|
uroot_reached = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,6 @@ public:
|
||||||
private:
|
private:
|
||||||
Crypto crypto;
|
Crypto crypto;
|
||||||
TRP trp;
|
TRP trp;
|
||||||
std::vector<u8> pkg;
|
|
||||||
u64 pkgSize = 0;
|
u64 pkgSize = 0;
|
||||||
char pkgTitleID[9];
|
char pkgTitleID[9];
|
||||||
PKGHeader pkgheader;
|
PKGHeader pkgheader;
|
||||||
|
|
|
@ -1,16 +1,75 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/io_file.h"
|
|
||||||
|
|
||||||
#include "playgo_chunk.h"
|
#include "playgo_chunk.h"
|
||||||
|
|
||||||
bool PlaygoChunk::Open(const std::filesystem::path& filepath) {
|
bool PlaygoFile::Open(const std::filesystem::path& filepath) {
|
||||||
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||||
if (!file.IsOpen()) {
|
if (file.IsOpen()) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
file.Read(playgoHeader);
|
file.Read(playgoHeader);
|
||||||
|
if (LoadChunks(file)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlaygoFile::LoadChunks(const Common::FS::IOFile& file) {
|
||||||
|
if (file.IsOpen()) {
|
||||||
|
if (playgoHeader.magic == PLAYGO_MAGIC) {
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
std::string chunk_attrs_data, chunk_mchunks_data, chunk_labels_data, mchunk_attrs_data;
|
||||||
|
ret = ret && load_chunk_data(file, playgoHeader.chunk_attrs, chunk_attrs_data);
|
||||||
|
ret = ret && load_chunk_data(file, playgoHeader.chunk_mchunks, chunk_mchunks_data);
|
||||||
|
ret = ret && load_chunk_data(file, playgoHeader.chunk_labels, chunk_labels_data);
|
||||||
|
ret = ret && load_chunk_data(file, playgoHeader.mchunk_attrs, mchunk_attrs_data);
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
chunks.resize(playgoHeader.chunk_count);
|
||||||
|
|
||||||
|
auto chunk_attrs =
|
||||||
|
reinterpret_cast<playgo_chunk_attr_entry_t*>(&chunk_attrs_data[0]);
|
||||||
|
auto chunk_mchunks = reinterpret_cast<u16*>(&chunk_mchunks_data[0]);
|
||||||
|
auto chunk_labels = reinterpret_cast<char*>(&chunk_labels_data[0]);
|
||||||
|
auto mchunk_attrs =
|
||||||
|
reinterpret_cast<playgo_mchunk_attr_entry_t*>(&mchunk_attrs_data[0]);
|
||||||
|
|
||||||
|
for (u16 i = 0; i < playgoHeader.chunk_count; i++) {
|
||||||
|
chunks[i].req_locus = chunk_attrs[i].req_locus;
|
||||||
|
chunks[i].language_mask = chunk_attrs[i].language_mask;
|
||||||
|
chunks[i].label_name = std::string(chunk_labels + chunk_attrs[i].label_offset);
|
||||||
|
|
||||||
|
u64 total_size = 0;
|
||||||
|
u16 mchunk_count = chunk_attrs[i].mchunk_count;
|
||||||
|
if (mchunk_count != 0) {
|
||||||
|
auto mchunks = reinterpret_cast<u16*>(
|
||||||
|
((u8*)chunk_mchunks + chunk_attrs[i].mchunks_offset));
|
||||||
|
for (u16 j = 0; j < mchunk_count; j++) {
|
||||||
|
u16 mchunk_id = mchunks[j];
|
||||||
|
total_size += mchunk_attrs[mchunk_id].size.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chunks[i].total_size = total_size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlaygoFile::load_chunk_data(const Common::FS::IOFile& file, const chunk_t chunk,
|
||||||
|
std::string& data) {
|
||||||
|
if (file.IsOpen()) {
|
||||||
|
if (file.Seek(chunk.offset)) {
|
||||||
|
data.resize(chunk.length);
|
||||||
|
if (data.size() == chunk.length) {
|
||||||
|
file.ReadRaw<char>(&data[0], chunk.length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -3,29 +3,129 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include "common/types.h"
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/io_file.h"
|
||||||
|
#include "core/libraries/playgo/playgo_types.h"
|
||||||
|
|
||||||
|
constexpr u32 PLAYGO_MAGIC = 0x6F676C70;
|
||||||
|
|
||||||
|
struct chunk_t {
|
||||||
|
u32 offset;
|
||||||
|
u32 length;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct PlaygoHeader {
|
struct PlaygoHeader {
|
||||||
u32 magic;
|
u32 magic;
|
||||||
|
|
||||||
u16 version_major;
|
u16 version_major;
|
||||||
u16 version_minor;
|
u16 version_minor;
|
||||||
u16 image_count;
|
u16 image_count; // [0;1]
|
||||||
|
u16 chunk_count; // [0;1000]
|
||||||
|
u16 mchunk_count; // [0;8000]
|
||||||
|
u16 scenario_count; // [0;32]
|
||||||
|
|
||||||
|
u32 file_size;
|
||||||
|
u16 default_scenario_id;
|
||||||
|
u16 attrib;
|
||||||
|
u32 sdk_version;
|
||||||
|
u16 disc_count; // [0;2] (if equals to 0 then disc count = 1)
|
||||||
|
u16 layer_bmp;
|
||||||
|
|
||||||
|
u8 reserved[32];
|
||||||
|
char content_id[128];
|
||||||
|
|
||||||
|
chunk_t chunk_attrs; // [0;32000]
|
||||||
|
chunk_t chunk_mchunks;
|
||||||
|
chunk_t chunk_labels; // [0;16000]
|
||||||
|
chunk_t mchunk_attrs; // [0;12800]
|
||||||
|
chunk_t scenario_attrs; // [0;1024]
|
||||||
|
chunk_t scenario_chunks;
|
||||||
|
chunk_t scenario_labels;
|
||||||
|
chunk_t inner_mchunk_attrs; // [0;12800]
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct playgo_scenario_attr_entry_t {
|
||||||
|
u8 _type;
|
||||||
|
u8 _unk[19];
|
||||||
|
u16 initial_chunk_count;
|
||||||
u16 chunk_count;
|
u16 chunk_count;
|
||||||
|
u32 chunks_offset; //<-scenario_chunks
|
||||||
|
u32 label_offset; //<-scenario_labels
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct image_disc_layer_no_t {
|
||||||
|
u8 layer_no : 2;
|
||||||
|
u8 disc_no : 2;
|
||||||
|
u8 image_no : 4;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct playgo_chunk_attr_entry_t {
|
||||||
|
u8 flag;
|
||||||
|
image_disc_layer_no_t image_disc_layer_no;
|
||||||
|
u8 req_locus;
|
||||||
|
u8 unk[11];
|
||||||
u16 mchunk_count;
|
u16 mchunk_count;
|
||||||
u16 scenario_count;
|
u64 language_mask;
|
||||||
// TODO fill the rest
|
u32 mchunks_offset; //<-chunk_mchunks
|
||||||
|
u32 label_offset; //<-chunk_labels
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct playgo_chunk_loc_t {
|
||||||
|
u64 offset : 48;
|
||||||
|
u64 _align1 : 8;
|
||||||
|
u64 image_no : 4;
|
||||||
|
u64 _align2 : 4;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct playgo_chunk_size_t {
|
||||||
|
u64 size : 48;
|
||||||
|
u64 _align : 16;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct playgo_mchunk_attr_entry_t {
|
||||||
|
playgo_chunk_loc_t loc;
|
||||||
|
playgo_chunk_size_t size;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct PlaygoChunk {
|
||||||
|
u64 req_locus;
|
||||||
|
u64 language_mask;
|
||||||
|
u64 total_size;
|
||||||
|
std::string label_name;
|
||||||
};
|
};
|
||||||
class PlaygoChunk {
|
|
||||||
|
class PlaygoFile {
|
||||||
public:
|
public:
|
||||||
PlaygoChunk() = default;
|
bool initialized;
|
||||||
~PlaygoChunk() = default;
|
OrbisPlayGoHandle handle;
|
||||||
|
OrbisPlayGoChunkId id;
|
||||||
|
OrbisPlayGoLocus locus;
|
||||||
|
OrbisPlayGoInstallSpeed speed;
|
||||||
|
s64 speed_tick;
|
||||||
|
OrbisPlayGoEta eta;
|
||||||
|
OrbisPlayGoLanguageMask langMask;
|
||||||
|
std::vector<PlaygoChunk> chunks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PlaygoFile()
|
||||||
|
: initialized(false), handle(0), id(0), locus(0), speed(ORBIS_PLAYGO_INSTALL_SPEED_TRICKLE),
|
||||||
|
speed_tick(0), eta(0), langMask(0), playgoHeader{0} {}
|
||||||
|
~PlaygoFile() = default;
|
||||||
|
|
||||||
bool Open(const std::filesystem::path& filepath);
|
bool Open(const std::filesystem::path& filepath);
|
||||||
PlaygoHeader GetPlaygoHeader() {
|
bool LoadChunks(const Common::FS::IOFile& file);
|
||||||
|
PlaygoHeader& GetPlaygoHeader() {
|
||||||
return playgoHeader;
|
return playgoHeader;
|
||||||
}
|
}
|
||||||
|
std::mutex& GetSpeedMutex() {
|
||||||
|
return speed_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool load_chunk_data(const Common::FS::IOFile& file, const chunk_t chunk, std::string& data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlaygoHeader playgoHeader;
|
PlaygoHeader playgoHeader;
|
||||||
|
std::mutex speed_mutex;
|
||||||
};
|
};
|
|
@ -9,7 +9,7 @@ PSF::PSF() = default;
|
||||||
|
|
||||||
PSF::~PSF() = default;
|
PSF::~PSF() = default;
|
||||||
|
|
||||||
bool PSF::open(const std::string& filepath, std::vector<u8> psfBuffer) {
|
bool PSF::open(const std::string& filepath, const std::vector<u8>& psfBuffer) {
|
||||||
if (!psfBuffer.empty()) {
|
if (!psfBuffer.empty()) {
|
||||||
psf.resize(psfBuffer.size());
|
psf.resize(psfBuffer.size());
|
||||||
psf = psfBuffer;
|
psf = psfBuffer;
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
PSF();
|
PSF();
|
||||||
~PSF();
|
~PSF();
|
||||||
|
|
||||||
bool open(const std::string& filepath, std::vector<u8> psfBuffer);
|
bool open(const std::string& filepath, const std::vector<u8>& psfBuffer);
|
||||||
|
|
||||||
std::string GetString(const std::string& key);
|
std::string GetString(const std::string& key);
|
||||||
u32 GetInteger(const std::string& key);
|
u32 GetInteger(const std::string& key);
|
||||||
|
|
|
@ -48,7 +48,7 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory) {
|
||||||
pos = mount->mount.size() + 1;
|
pos = mount->mount.size() + 1;
|
||||||
const auto rel_path = std::string_view(corrected_path).substr(pos);
|
const auto rel_path = std::string_view(corrected_path).substr(pos);
|
||||||
const auto host_path = mount->host_path / rel_path;
|
const auto host_path = mount->host_path / rel_path;
|
||||||
if (!NeedsCaseInsensiveSearch) {
|
if (!NeedsCaseInsensitiveSearch) {
|
||||||
return host_path;
|
return host_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace Core::FileSys {
|
||||||
|
|
||||||
class MntPoints {
|
class MntPoints {
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
static constexpr bool NeedsCaseInsensiveSearch = false;
|
static constexpr bool NeedsCaseInsensitiveSearch = false;
|
||||||
#else
|
#else
|
||||||
static constexpr bool NeedsCaseInsensiveSearch = true;
|
static constexpr bool NeedsCaseInsensitiveSearch = true;
|
||||||
#endif
|
#endif
|
||||||
public:
|
public:
|
||||||
struct MntPair {
|
struct MntPair {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
#include "ajm.h"
|
||||||
|
#include "ajm_error.h"
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/ajm/ajm.h"
|
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
constexpr int ORBIS_AJM_ERROR_UNKNOWN = 0x80930001;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_CONTEXT = 0x80930002;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_INSTANCE = 0x80930003;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_BATCH = 0x80930004;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_PARAMETER = 0x80930005;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_OUT_OF_MEMORY = 0x80930006;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_OUT_OF_RESOURCES = 0x80930007;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_CODEC_NOT_SUPPORTED = 0x80930008;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_CODEC_ALREADY_REGISTERED = 0x80930009;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_CODEC_NOT_REGISTERED = 0x8093000A;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_WRONG_REVISION_FLAG = 0x8093000B;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_FLAG_NOT_SUPPORTED = 0x8093000C;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_BUSY = 0x8093000D;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_BAD_PRIORITY = 0x8093000E;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_IN_PROGRESS = 0x8093000F;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_RETRY = 0x80930010;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_MALFORMED_BATCH = 0x80930011;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_JOB_CREATION = 0x80930012;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_OPCODE = 0x80930013;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_PRIORITY_VIOLATION = 0x80930014;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_BUFFER_TOO_BIG = 0x80930015;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_INVALID_ADDRESS = 0x80930016;
|
||||||
|
constexpr int ORBIS_AJM_ERROR_CANCELLED = 0x80930017;
|
|
@ -1,20 +1,38 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <common/path_util.h>
|
|
||||||
#include <common/singleton.h>
|
|
||||||
#include <core/file_format/psf.h>
|
|
||||||
#include <core/file_sys/fs.h>
|
|
||||||
#include "app_content.h"
|
#include "app_content.h"
|
||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/path_util.h"
|
||||||
|
#include "common/singleton.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
|
#include "core/file_format/psf.h"
|
||||||
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
||||||
namespace Libraries::AppContent {
|
namespace Libraries::AppContent {
|
||||||
|
|
||||||
|
int32_t addcont_count = 0;
|
||||||
|
|
||||||
|
struct AddContInfo {
|
||||||
|
char entitlementLabel[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE];
|
||||||
|
OrbisAppContentAddcontDownloadStatus status;
|
||||||
|
OrbisAppContentGetEntitlementKey key;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::array<AddContInfo, ORBIS_APP_CONTENT_INFO_LIST_MAX_SIZE> addcont_info = {{
|
||||||
|
{"0000000000000000",
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED,
|
||||||
|
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00}},
|
||||||
|
}};
|
||||||
|
|
||||||
|
std::string title_id;
|
||||||
|
|
||||||
int PS4_SYSV_ABI _Z5dummyv() {
|
int PS4_SYSV_ABI _Z5dummyv() {
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -35,11 +53,33 @@ int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadSp() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontMount() {
|
int PS4_SYSV_ABI sceAppContentAddcontMount(u32 service_label,
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
const OrbisNpUnifiedEntitlementLabel* entitlement_label,
|
||||||
|
OrbisAppContentMountPoint* mount_point) {
|
||||||
|
LOG_INFO(Lib_AppContent, "called");
|
||||||
|
|
||||||
|
const auto& mount_dir = Common::FS::GetUserPath(Common::FS::PathType::AddonsDir) / title_id /
|
||||||
|
entitlement_label->data;
|
||||||
|
auto* mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
|
||||||
|
for (int i = 0; i < addcont_count; i++) {
|
||||||
|
if (strncmp(entitlement_label->data, addcont_info[i].entitlementLabel,
|
||||||
|
ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addcont_info[i].status != ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED) {
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(mount_point->data, ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE, "/addcont%d", i);
|
||||||
|
mnt->Mount(mount_dir, mount_point->data);
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontShrink() {
|
int PS4_SYSV_ABI sceAppContentAddcontShrink() {
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -124,24 +164,82 @@ int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfo() {
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label,
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
const OrbisNpUnifiedEntitlementLabel* entitlementLabel,
|
||||||
|
OrbisAppContentAddcontInfo* info) {
|
||||||
|
LOG_INFO(Lib_AppContent, "called");
|
||||||
|
|
||||||
|
if (entitlementLabel == nullptr || info == nullptr) {
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto i = 0; i < addcont_count; i++) {
|
||||||
|
if (strncmp(entitlementLabel->data, addcont_info[i].entitlementLabel,
|
||||||
|
ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(Lib_AppContent, "found DLC {}", entitlementLabel->data);
|
||||||
|
|
||||||
|
strncpy(info->entitlement_label.data, addcont_info[i].entitlementLabel,
|
||||||
|
ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE);
|
||||||
|
info->status = addcont_info[i].status;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
|
||||||
OrbisAppContentAddcontInfo* list, u32 list_num,
|
OrbisAppContentAddcontInfo* list, u32 list_num,
|
||||||
u32* hit_num) {
|
u32* hit_num) {
|
||||||
*hit_num = 0;
|
LOG_INFO(Lib_AppContent, "called");
|
||||||
LOG_ERROR(Lib_AppContent, "(DUMMY) called");
|
|
||||||
|
if (list_num == 0 || list == nullptr) {
|
||||||
|
if (hit_num == nullptr) {
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
*hit_num = addcont_count;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentGetEntitlementKey() {
|
int dlcs_to_list = addcont_count < list_num ? addcont_count : list_num;
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
for (int i = 0; i < dlcs_to_list; i++) {
|
||||||
|
strncpy(list[i].entitlement_label.data, addcont_info[i].entitlementLabel,
|
||||||
|
ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE);
|
||||||
|
list[i].status = addcont_info[i].status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hit_num != nullptr) {
|
||||||
|
*hit_num = dlcs_to_list;
|
||||||
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAppContentGetEntitlementKey(
|
||||||
|
u32 service_label, const OrbisNpUnifiedEntitlementLabel* entitlement_label,
|
||||||
|
OrbisAppContentGetEntitlementKey* key) {
|
||||||
|
LOG_ERROR(Lib_AppContent, "called");
|
||||||
|
|
||||||
|
if (entitlement_label == nullptr || key == nullptr) {
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < addcont_count; i++) {
|
||||||
|
if (strncmp(entitlement_label->data, addcont_info[i].entitlementLabel,
|
||||||
|
ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(key->data, addcont_info[i].key.data, ORBIS_APP_CONTENT_ENTITLEMENT_KEY_SIZE);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentGetRegion() {
|
int PS4_SYSV_ABI sceAppContentGetRegion() {
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -150,7 +248,25 @@ int PS4_SYSV_ABI sceAppContentGetRegion() {
|
||||||
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,
|
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,
|
||||||
OrbisAppContentBootParam* bootParam) {
|
OrbisAppContentBootParam* bootParam) {
|
||||||
LOG_ERROR(Lib_AppContent, "(DUMMY) called");
|
LOG_ERROR(Lib_AppContent, "(DUMMY) called");
|
||||||
bootParam->attr = 0; // always 0
|
auto* param_sfo = Common::Singleton<PSF>::Instance();
|
||||||
|
|
||||||
|
const auto addons_dir = Common::FS::GetUserPath(Common::FS::PathType::AddonsDir);
|
||||||
|
title_id = param_sfo->GetString("TITLE_ID");
|
||||||
|
auto addon_path = addons_dir / title_id;
|
||||||
|
if (std::filesystem::exists(addon_path)) {
|
||||||
|
for (const auto& entry : std::filesystem::directory_iterator(addon_path)) {
|
||||||
|
if (entry.is_directory()) {
|
||||||
|
auto entitlement_label = entry.path().filename().string();
|
||||||
|
|
||||||
|
AddContInfo info{};
|
||||||
|
info.status = ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED;
|
||||||
|
strcpy(info.entitlementLabel, entitlement_label.c_str());
|
||||||
|
|
||||||
|
addcont_info[addcont_count++] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,12 +337,12 @@ int PS4_SYSV_ABI Func_C59A36FF8D7C59DA() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlemetId() {
|
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlementId() {
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlemetId() {
|
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlementId() {
|
||||||
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
LOG_ERROR(Lib_AppContent, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -313,9 +429,9 @@ void RegisterlibSceAppContent(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("xZo2-418Wdo", "libSceAppContentBundle", 1, "libSceAppContent", 1, 1,
|
LIB_FUNCTION("xZo2-418Wdo", "libSceAppContentBundle", 1, "libSceAppContent", 1, 1,
|
||||||
Func_C59A36FF8D7C59DA);
|
Func_C59A36FF8D7C59DA);
|
||||||
LIB_FUNCTION("kJmjt81mXKQ", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
LIB_FUNCTION("kJmjt81mXKQ", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
||||||
sceAppContentAddcontEnqueueDownloadByEntitlemetId);
|
sceAppContentAddcontEnqueueDownloadByEntitlementId);
|
||||||
LIB_FUNCTION("efX3lrPwdKA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
LIB_FUNCTION("efX3lrPwdKA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
||||||
sceAppContentAddcontMountByEntitlemetId);
|
sceAppContentAddcontMountByEntitlementId);
|
||||||
LIB_FUNCTION("z9hgjLd1SGA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
LIB_FUNCTION("z9hgjLd1SGA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
||||||
sceAppContentGetAddcontInfoByEntitlementId);
|
sceAppContentGetAddcontInfoByEntitlementId);
|
||||||
LIB_FUNCTION("3wUaDTGmjcQ", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
LIB_FUNCTION("3wUaDTGmjcQ", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
|
||||||
|
|
|
@ -41,6 +41,16 @@ struct OrbisAppContentMountPoint {
|
||||||
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_NONE = 0;
|
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_NONE = 0;
|
||||||
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_FORMAT = (1 << 0);
|
constexpr int ORBIS_APP_CONTENT_TEMPORARY_DATA_OPTION_FORMAT = (1 << 0);
|
||||||
constexpr int ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE = 17;
|
constexpr int ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE = 17;
|
||||||
|
constexpr int ORBIS_APP_CONTENT_ENTITLEMENT_KEY_SIZE = 16;
|
||||||
|
constexpr int ORBIS_APP_CONTENT_INFO_LIST_MAX_SIZE = 2500;
|
||||||
|
|
||||||
|
enum OrbisAppContentAddcontDownloadStatus : u32 {
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_NO_EXTRA_DATA = 0,
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_NO_IN_QUEUE = 1,
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_DOWNLOADING = 2,
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_DOWNLOAD_SUSPENDED = 3,
|
||||||
|
ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED = 4
|
||||||
|
};
|
||||||
|
|
||||||
struct OrbisNpUnifiedEntitlementLabel {
|
struct OrbisNpUnifiedEntitlementLabel {
|
||||||
char data[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE];
|
char data[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE];
|
||||||
|
@ -54,11 +64,17 @@ struct OrbisAppContentAddcontInfo {
|
||||||
u32 status;
|
u32 status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OrbisAppContentGetEntitlementKey {
|
||||||
|
char data[ORBIS_APP_CONTENT_ENTITLEMENT_KEY_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
int PS4_SYSV_ABI _Z5dummyv();
|
int PS4_SYSV_ABI _Z5dummyv();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontDelete();
|
int PS4_SYSV_ABI sceAppContentAddcontDelete();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownload();
|
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownload();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadSp();
|
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadSp();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontMount();
|
int PS4_SYSV_ABI sceAppContentAddcontMount(u32 service_label,
|
||||||
|
const OrbisNpUnifiedEntitlementLabel* entitlement_label,
|
||||||
|
OrbisAppContentMountPoint* mount_point);
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontShrink();
|
int PS4_SYSV_ABI sceAppContentAddcontShrink();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontUnmount();
|
int PS4_SYSV_ABI sceAppContentAddcontUnmount();
|
||||||
int PS4_SYSV_ABI sceAppContentAppParamGetInt(OrbisAppContentAppParamId paramId, s32* value);
|
int PS4_SYSV_ABI sceAppContentAppParamGetInt(OrbisAppContentAppParamId paramId, s32* value);
|
||||||
|
@ -70,11 +86,15 @@ int PS4_SYSV_ABI sceAppContentDownload1Shrink();
|
||||||
int PS4_SYSV_ABI sceAppContentDownloadDataFormat();
|
int PS4_SYSV_ABI sceAppContentDownloadDataFormat();
|
||||||
int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb();
|
int PS4_SYSV_ABI sceAppContentDownloadDataGetAvailableSpaceKb();
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress();
|
int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress();
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfo();
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label,
|
||||||
|
const OrbisNpUnifiedEntitlementLabel* entitlementLabel,
|
||||||
|
OrbisAppContentAddcontInfo* info);
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label,
|
||||||
OrbisAppContentAddcontInfo* list, u32 list_num,
|
OrbisAppContentAddcontInfo* list, u32 list_num,
|
||||||
u32* hit_num);
|
u32* hit_num);
|
||||||
int PS4_SYSV_ABI sceAppContentGetEntitlementKey();
|
int PS4_SYSV_ABI sceAppContentGetEntitlementKey(
|
||||||
|
u32 service_label, const OrbisNpUnifiedEntitlementLabel* entitlement_label,
|
||||||
|
OrbisAppContentGetEntitlementKey* key);
|
||||||
int PS4_SYSV_ABI sceAppContentGetRegion();
|
int PS4_SYSV_ABI sceAppContentGetRegion();
|
||||||
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,
|
int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initParam,
|
||||||
OrbisAppContentBootParam* bootParam);
|
OrbisAppContentBootParam* bootParam);
|
||||||
|
@ -92,8 +112,8 @@ int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOp
|
||||||
int PS4_SYSV_ABI sceAppContentTemporaryDataUnmount();
|
int PS4_SYSV_ABI sceAppContentTemporaryDataUnmount();
|
||||||
int PS4_SYSV_ABI sceAppContentGetPftFlag();
|
int PS4_SYSV_ABI sceAppContentGetPftFlag();
|
||||||
int PS4_SYSV_ABI Func_C59A36FF8D7C59DA();
|
int PS4_SYSV_ABI Func_C59A36FF8D7C59DA();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlemetId();
|
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlementId();
|
||||||
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlemetId();
|
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlementId();
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfoByEntitlementId();
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfoByEntitlementId();
|
||||||
int PS4_SYSV_ABI sceAppContentGetAddcontInfoListByIroTag();
|
int PS4_SYSV_ABI sceAppContentGetAddcontInfoListByIroTag();
|
||||||
int PS4_SYSV_ABI sceAppContentGetDownloadedStoreCountry();
|
int PS4_SYSV_ABI sceAppContentGetDownloadedStoreCountry();
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <common/assert.h>
|
|
||||||
#include <magic_enum.hpp>
|
#include <magic_enum.hpp>
|
||||||
|
|
||||||
#include "audio_core/sdl_audio.h"
|
#include "audio_core/sdl_audio.h"
|
||||||
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/audio/audioout.h"
|
#include "core/libraries/audio/audioout.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
|
|
|
@ -40,9 +40,11 @@ int PS4_SYSV_ABI sceAvPlayerChangeStream() {
|
||||||
s32 PS4_SYSV_ABI sceAvPlayerClose(SceAvPlayerHandle handle) {
|
s32 PS4_SYSV_ABI sceAvPlayerClose(SceAvPlayerHandle handle) {
|
||||||
LOG_TRACE(Lib_AvPlayer, "called");
|
LOG_TRACE(Lib_AvPlayer, "called");
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
|
LOG_TRACE(Lib_AvPlayer, "returning ORBIS_AVPLAYER_ERROR_INVALID_PARAMS");
|
||||||
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
delete handle;
|
delete handle;
|
||||||
|
LOG_TRACE(Lib_AvPlayer, "returning ORBIS_OK");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -257,6 +259,7 @@ s32 PS4_SYSV_ABI sceAvPlayerStart(SceAvPlayerHandle handle) {
|
||||||
s32 PS4_SYSV_ABI sceAvPlayerStop(SceAvPlayerHandle handle) {
|
s32 PS4_SYSV_ABI sceAvPlayerStop(SceAvPlayerHandle handle) {
|
||||||
LOG_TRACE(Lib_AvPlayer, "called");
|
LOG_TRACE(Lib_AvPlayer, "called");
|
||||||
if (handle == nullptr) {
|
if (handle == nullptr) {
|
||||||
|
LOG_TRACE(Lib_AvPlayer, "returning ORBIS_AVPLAYER_ERROR_INVALID_PARAMS");
|
||||||
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
const auto res = handle->Stop();
|
const auto res = handle->Stop();
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
struct AVIOContext;
|
struct AVIOContext;
|
||||||
|
|
||||||
namespace Libraries::AvPlayer {
|
namespace Libraries::AvPlayer {
|
||||||
|
@ -14,6 +16,7 @@ namespace Libraries::AvPlayer {
|
||||||
class IDataStreamer {
|
class IDataStreamer {
|
||||||
public:
|
public:
|
||||||
virtual ~IDataStreamer() = default;
|
virtual ~IDataStreamer() = default;
|
||||||
|
virtual bool Init(std::string_view path) = 0;
|
||||||
virtual AVIOContext* GetContext() = 0;
|
virtual AVIOContext* GetContext() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -18,19 +18,8 @@ extern "C" {
|
||||||
|
|
||||||
namespace Libraries::AvPlayer {
|
namespace Libraries::AvPlayer {
|
||||||
|
|
||||||
AvPlayerFileStreamer::AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement,
|
AvPlayerFileStreamer::AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement)
|
||||||
std::string_view path)
|
: m_file_replacement(file_replacement) {}
|
||||||
: m_file_replacement(file_replacement) {
|
|
||||||
const auto ptr = m_file_replacement.object_ptr;
|
|
||||||
m_fd = m_file_replacement.open(ptr, path.data());
|
|
||||||
ASSERT(m_fd >= 0);
|
|
||||||
m_file_size = m_file_replacement.size(ptr);
|
|
||||||
// avio_buffer is deallocated in `avio_context_free`
|
|
||||||
const auto avio_buffer = reinterpret_cast<u8*>(av_malloc(AVPLAYER_AVIO_BUFFER_SIZE));
|
|
||||||
m_avio_context =
|
|
||||||
avio_alloc_context(avio_buffer, AVPLAYER_AVIO_BUFFER_SIZE, 0, this,
|
|
||||||
&AvPlayerFileStreamer::ReadPacket, nullptr, &AvPlayerFileStreamer::Seek);
|
|
||||||
}
|
|
||||||
|
|
||||||
AvPlayerFileStreamer::~AvPlayerFileStreamer() {
|
AvPlayerFileStreamer::~AvPlayerFileStreamer() {
|
||||||
if (m_avio_context != nullptr) {
|
if (m_avio_context != nullptr) {
|
||||||
|
@ -43,6 +32,21 @@ AvPlayerFileStreamer::~AvPlayerFileStreamer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AvPlayerFileStreamer::Init(std::string_view path) {
|
||||||
|
const auto ptr = m_file_replacement.object_ptr;
|
||||||
|
m_fd = m_file_replacement.open(ptr, path.data());
|
||||||
|
if (m_fd < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_file_size = m_file_replacement.size(ptr);
|
||||||
|
// avio_buffer is deallocated in `avio_context_free`
|
||||||
|
const auto avio_buffer = reinterpret_cast<u8*>(av_malloc(AVPLAYER_AVIO_BUFFER_SIZE));
|
||||||
|
m_avio_context =
|
||||||
|
avio_alloc_context(avio_buffer, AVPLAYER_AVIO_BUFFER_SIZE, 0, this,
|
||||||
|
&AvPlayerFileStreamer::ReadPacket, nullptr, &AvPlayerFileStreamer::Seek);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
s32 AvPlayerFileStreamer::ReadPacket(void* opaque, u8* buffer, s32 size) {
|
s32 AvPlayerFileStreamer::ReadPacket(void* opaque, u8* buffer, s32 size) {
|
||||||
const auto self = reinterpret_cast<AvPlayerFileStreamer*>(opaque);
|
const auto self = reinterpret_cast<AvPlayerFileStreamer*>(opaque);
|
||||||
if (self->m_position >= self->m_file_size) {
|
if (self->m_position >= self->m_file_size) {
|
||||||
|
|
|
@ -15,9 +15,11 @@ namespace Libraries::AvPlayer {
|
||||||
|
|
||||||
class AvPlayerFileStreamer : public IDataStreamer {
|
class AvPlayerFileStreamer : public IDataStreamer {
|
||||||
public:
|
public:
|
||||||
AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement, std::string_view path);
|
AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement);
|
||||||
~AvPlayerFileStreamer();
|
~AvPlayerFileStreamer();
|
||||||
|
|
||||||
|
bool Init(std::string_view path) override;
|
||||||
|
|
||||||
AVIOContext* GetContext() override {
|
AVIOContext* GetContext() override {
|
||||||
return m_avio_context;
|
return m_avio_context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ s32 AvPlayer::AddSource(std::string_view path) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
return ORBIS_AVPLAYER_ERROR_INVALID_PARAMS;
|
||||||
}
|
}
|
||||||
if (AVPLAYER_IS_ERROR(m_state->AddSource(path, GetSourceType(path)))) {
|
if (!m_state->AddSource(path, GetSourceType(path))) {
|
||||||
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
|
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -128,7 +128,7 @@ s32 AvPlayer::GetStreamCount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 AvPlayer::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
s32 AvPlayer::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
||||||
if (AVPLAYER_IS_ERROR(m_state->GetStreamInfo(stream_index, info))) {
|
if (!m_state->GetStreamInfo(stream_index, info)) {
|
||||||
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
|
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -145,7 +145,10 @@ s32 AvPlayer::EnableStream(u32 stream_index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 AvPlayer::Start() {
|
s32 AvPlayer::Start() {
|
||||||
return m_state->Start();
|
if (!m_state->Start()) {
|
||||||
|
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvPlayer::GetVideoData(SceAvPlayerFrameInfo& video_info) {
|
bool AvPlayer::GetVideoData(SceAvPlayerFrameInfo& video_info) {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include "avplayer_file_streamer.h"
|
#include "avplayer_file_streamer.h"
|
||||||
|
|
||||||
|
#include "common/alignment.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/kernel/time_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
|
@ -23,31 +24,39 @@ namespace Libraries::AvPlayer {
|
||||||
|
|
||||||
using namespace Kernel;
|
using namespace Kernel;
|
||||||
|
|
||||||
AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state, std::string_view path,
|
AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state) : m_state(state) {}
|
||||||
const SceAvPlayerInitData& init_data,
|
|
||||||
SceAvPlayerSourceType source_type)
|
|
||||||
: m_state(state), m_memory_replacement(init_data.memory_replacement),
|
|
||||||
m_num_output_video_framebuffers(
|
|
||||||
std::min(std::max(2, init_data.num_output_video_framebuffers), 16)) {
|
|
||||||
AVFormatContext* context = avformat_alloc_context();
|
|
||||||
if (init_data.file_replacement.open != nullptr) {
|
|
||||||
m_up_data_streamer =
|
|
||||||
std::make_unique<AvPlayerFileStreamer>(init_data.file_replacement, path);
|
|
||||||
context->pb = m_up_data_streamer->GetContext();
|
|
||||||
ASSERT(!AVPLAYER_IS_ERROR(avformat_open_input(&context, nullptr, nullptr, nullptr)));
|
|
||||||
} else {
|
|
||||||
const auto mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
|
||||||
const auto filepath = mnt->GetHostPath(path);
|
|
||||||
ASSERT(!AVPLAYER_IS_ERROR(
|
|
||||||
avformat_open_input(&context, filepath.string().c_str(), nullptr, nullptr)));
|
|
||||||
}
|
|
||||||
m_avformat_context = AVFormatContextPtr(context, &ReleaseAVFormatContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
AvPlayerSource::~AvPlayerSource() {
|
AvPlayerSource::~AvPlayerSource() {
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AvPlayerSource::Init(const SceAvPlayerInitData& init_data, std::string_view path) {
|
||||||
|
m_memory_replacement = init_data.memory_replacement,
|
||||||
|
m_num_output_video_framebuffers =
|
||||||
|
std::min(std::max(2, init_data.num_output_video_framebuffers), 16);
|
||||||
|
|
||||||
|
AVFormatContext* context = avformat_alloc_context();
|
||||||
|
if (init_data.file_replacement.open != nullptr) {
|
||||||
|
m_up_data_streamer = std::make_unique<AvPlayerFileStreamer>(init_data.file_replacement);
|
||||||
|
if (!m_up_data_streamer->Init(path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
context->pb = m_up_data_streamer->GetContext();
|
||||||
|
if (AVPLAYER_IS_ERROR(avformat_open_input(&context, nullptr, nullptr, nullptr))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
|
||||||
|
const auto filepath = mnt->GetHostPath(path);
|
||||||
|
if (AVPLAYER_IS_ERROR(
|
||||||
|
avformat_open_input(&context, filepath.string().c_str(), nullptr, nullptr))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_avformat_context = AVFormatContextPtr(context, &ReleaseAVFormatContext);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool AvPlayerSource::FindStreamInfo() {
|
bool AvPlayerSource::FindStreamInfo() {
|
||||||
if (m_avformat_context == nullptr) {
|
if (m_avformat_context == nullptr) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not find stream info. NULL context.");
|
LOG_ERROR(Lib_AvPlayer, "Could not find stream info. NULL context.");
|
||||||
|
@ -82,20 +91,20 @@ static s32 CodecTypeToStreamType(AVMediaType codec_type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static f32 AVRationalToF32(const AVRational& rational) {
|
static f32 AVRationalToF32(const AVRational rational) {
|
||||||
return f32(rational.num) / rational.den;
|
return f32(rational.num) / rational.den;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
||||||
info = {};
|
info = {};
|
||||||
if (m_avformat_context == nullptr || stream_index >= m_avformat_context->nb_streams) {
|
if (m_avformat_context == nullptr || stream_index >= m_avformat_context->nb_streams) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info.", stream_index);
|
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info.", stream_index);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
const auto p_stream = m_avformat_context->streams[stream_index];
|
const auto p_stream = m_avformat_context->streams[stream_index];
|
||||||
if (p_stream == nullptr || p_stream->codecpar == nullptr) {
|
if (p_stream == nullptr || p_stream->codecpar == nullptr) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info. NULL stream.", stream_index);
|
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info. NULL stream.", stream_index);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
info.type = CodecTypeToStreamType(p_stream->codecpar->codec_type);
|
info.type = CodecTypeToStreamType(p_stream->codecpar->codec_type);
|
||||||
info.start_time = p_stream->start_time;
|
info.start_time = p_stream->start_time;
|
||||||
|
@ -111,8 +120,8 @@ s32 AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info)
|
||||||
LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index);
|
LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index);
|
||||||
info.details.video.aspect_ratio =
|
info.details.video.aspect_ratio =
|
||||||
f32(p_stream->codecpar->width) / p_stream->codecpar->height;
|
f32(p_stream->codecpar->width) / p_stream->codecpar->height;
|
||||||
info.details.video.width = p_stream->codecpar->width;
|
info.details.video.width = Common::AlignUp(u32(p_stream->codecpar->width), 16);
|
||||||
info.details.video.height = p_stream->codecpar->height;
|
info.details.video.height = Common::AlignUp(u32(p_stream->codecpar->height), 16);
|
||||||
if (p_lang_node != nullptr) {
|
if (p_lang_node != nullptr) {
|
||||||
std::memcpy(info.details.video.language_code, p_lang_node->value,
|
std::memcpy(info.details.video.language_code, p_lang_node->value,
|
||||||
std::min(strlen(p_lang_node->value), size_t(3)));
|
std::min(strlen(p_lang_node->value), size_t(3)));
|
||||||
|
@ -139,9 +148,9 @@ s32 AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, info.type);
|
LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, info.type);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvPlayerSource::EnableStream(u32 stream_index) {
|
bool AvPlayerSource::EnableStream(u32 stream_index) {
|
||||||
|
@ -167,8 +176,9 @@ bool AvPlayerSource::EnableStream(u32 stream_index) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for video stream {}.", stream_index);
|
LOG_ERROR(Lib_AvPlayer, "Could not open avcodec for video stream {}.", stream_index);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto width = m_video_codec_context->width;
|
const auto width = Common::AlignUp(u32(m_video_codec_context->width), 16);
|
||||||
const auto size = (width * m_video_codec_context->height * 3) / 2;
|
const auto height = Common::AlignUp(u32(m_video_codec_context->height), 16);
|
||||||
|
const auto size = (width * height * 3) / 2;
|
||||||
for (u64 index = 0; index < m_num_output_video_framebuffers; ++index) {
|
for (u64 index = 0; index < m_num_output_video_framebuffers; ++index) {
|
||||||
m_video_buffers.Push(FrameBuffer(m_memory_replacement, 0x100, size));
|
m_video_buffers.Push(FrameBuffer(m_memory_replacement, 0x100, size));
|
||||||
}
|
}
|
||||||
|
@ -213,12 +223,12 @@ std::optional<bool> AvPlayerSource::HasFrames(u32 num_frames) {
|
||||||
return m_video_packets.Size() > num_frames || m_is_eof;
|
return m_video_packets.Size() > num_frames || m_is_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 AvPlayerSource::Start() {
|
bool AvPlayerSource::Start() {
|
||||||
std::unique_lock lock(m_state_mutex);
|
std::unique_lock lock(m_state_mutex);
|
||||||
|
|
||||||
if (m_audio_codec_context == nullptr && m_video_codec_context == nullptr) {
|
if (m_audio_codec_context == nullptr && m_video_codec_context == nullptr) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not start playback. NULL context.");
|
LOG_ERROR(Lib_AvPlayer, "Could not start playback. NULL context.");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
m_demuxer_thread = std::jthread([this](std::stop_token stop) { this->DemuxerThread(stop); });
|
m_demuxer_thread = std::jthread([this](std::stop_token stop) { this->DemuxerThread(stop); });
|
||||||
m_video_decoder_thread =
|
m_video_decoder_thread =
|
||||||
|
@ -226,7 +236,7 @@ s32 AvPlayerSource::Start() {
|
||||||
m_audio_decoder_thread =
|
m_audio_decoder_thread =
|
||||||
std::jthread([this](std::stop_token stop) { this->AudioDecoderThread(stop); });
|
std::jthread([this](std::stop_token stop) { this->AudioDecoderThread(stop); });
|
||||||
m_start_time = std::chrono::high_resolution_clock::now();
|
m_start_time = std::chrono::high_resolution_clock::now();
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvPlayerSource::Stop() {
|
bool AvPlayerSource::Stop() {
|
||||||
|
@ -284,11 +294,6 @@ bool AvPlayerSource::GetVideoData(SceAvPlayerFrameInfo& video_info) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CopyNV12Data(u8* dst, const AVFrame& src) {
|
|
||||||
std::memcpy(dst, src.data[0], src.width * src.height);
|
|
||||||
std::memcpy(dst + src.width * src.height, src.data[1], (src.width * src.height) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AvPlayerSource::GetVideoData(SceAvPlayerFrameInfoEx& video_info) {
|
bool AvPlayerSource::GetVideoData(SceAvPlayerFrameInfoEx& video_info) {
|
||||||
if (!IsActive()) {
|
if (!IsActive()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -359,12 +364,16 @@ bool AvPlayerSource::GetAudioData(SceAvPlayerFrameInfo& audio_info) {
|
||||||
audio_info = {};
|
audio_info = {};
|
||||||
audio_info.timestamp = frame->info.timestamp;
|
audio_info.timestamp = frame->info.timestamp;
|
||||||
audio_info.pData = reinterpret_cast<u8*>(frame->info.pData);
|
audio_info.pData = reinterpret_cast<u8*>(frame->info.pData);
|
||||||
|
audio_info.details.audio.sample_rate = frame->info.details.audio.sample_rate;
|
||||||
audio_info.details.audio.size = frame->info.details.audio.size;
|
audio_info.details.audio.size = frame->info.details.audio.size;
|
||||||
audio_info.details.audio.channel_count = frame->info.details.audio.channel_count;
|
audio_info.details.audio.channel_count = frame->info.details.audio.channel_count;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 AvPlayerSource::CurrentTime() {
|
u64 AvPlayerSource::CurrentTime() {
|
||||||
|
if (!IsActive()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
return duration_cast<milliseconds>(high_resolution_clock::now() - m_start_time).count();
|
return duration_cast<milliseconds>(high_resolution_clock::now() - m_start_time).count();
|
||||||
}
|
}
|
||||||
|
@ -489,13 +498,17 @@ AvPlayerSource::AVFramePtr AvPlayerSource::ConvertVideoFrame(const AVFrame& fram
|
||||||
nv12_frame->width = frame.width;
|
nv12_frame->width = frame.width;
|
||||||
nv12_frame->height = frame.height;
|
nv12_frame->height = frame.height;
|
||||||
nv12_frame->sample_aspect_ratio = frame.sample_aspect_ratio;
|
nv12_frame->sample_aspect_ratio = frame.sample_aspect_ratio;
|
||||||
|
nv12_frame->crop_top = frame.crop_top;
|
||||||
|
nv12_frame->crop_bottom = frame.crop_bottom;
|
||||||
|
nv12_frame->crop_left = frame.crop_left;
|
||||||
|
nv12_frame->crop_right = frame.crop_right;
|
||||||
|
|
||||||
av_frame_get_buffer(nv12_frame.get(), 0);
|
av_frame_get_buffer(nv12_frame.get(), 0);
|
||||||
|
|
||||||
if (m_sws_context == nullptr) {
|
if (m_sws_context == nullptr) {
|
||||||
m_sws_context =
|
m_sws_context =
|
||||||
SWSContextPtr(sws_getContext(frame.width, frame.height, AVPixelFormat(frame.format),
|
SWSContextPtr(sws_getContext(frame.width, frame.height, AVPixelFormat(frame.format),
|
||||||
frame.width, frame.height, AV_PIX_FMT_NV12,
|
nv12_frame->width, nv12_frame->height, AV_PIX_FMT_NV12,
|
||||||
SWS_FAST_BILINEAR, nullptr, nullptr, nullptr),
|
SWS_FAST_BILINEAR, nullptr, nullptr, nullptr),
|
||||||
&ReleaseSWSContext);
|
&ReleaseSWSContext);
|
||||||
}
|
}
|
||||||
|
@ -508,6 +521,26 @@ AvPlayerSource::AVFramePtr AvPlayerSource::ConvertVideoFrame(const AVFrame& fram
|
||||||
return nv12_frame;
|
return nv12_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CopyNV12Data(u8* dst, const AVFrame& src) {
|
||||||
|
const auto width = Common::AlignUp(u32(src.width), 16);
|
||||||
|
const auto height = Common::AlignUp(u32(src.height), 16);
|
||||||
|
|
||||||
|
if (src.width == width) {
|
||||||
|
std::memcpy(dst, src.data[0], src.width * src.height);
|
||||||
|
std::memcpy(dst + src.width * height, src.data[1], (src.width * src.height) / 2);
|
||||||
|
} else {
|
||||||
|
const auto luma_dst = dst;
|
||||||
|
for (u32 y = 0; y < src.height; ++y) {
|
||||||
|
std::memcpy(luma_dst + y * width, src.data[0] + y * src.width, src.width);
|
||||||
|
}
|
||||||
|
const auto chroma_dst = dst + width * height;
|
||||||
|
for (u32 y = 0; y < src.height / 2; ++y) {
|
||||||
|
std::memcpy(chroma_dst + y * (width / 2), src.data[0] + y * (src.width / 2),
|
||||||
|
src.width / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame) {
|
Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame) {
|
||||||
ASSERT(frame.format == AV_PIX_FMT_NV12);
|
ASSERT(frame.format == AV_PIX_FMT_NV12);
|
||||||
|
|
||||||
|
@ -521,6 +554,9 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
|
||||||
const auto num = time_base.num;
|
const auto num = time_base.num;
|
||||||
const auto timestamp = (num != 0 && den > 1) ? (pkt_dts * num) / den : pkt_dts;
|
const auto timestamp = (num != 0 && den > 1) ? (pkt_dts * num) / den : pkt_dts;
|
||||||
|
|
||||||
|
const auto width = Common::AlignUp(u32(frame.width), 16);
|
||||||
|
const auto height = Common::AlignUp(u32(frame.height), 16);
|
||||||
|
|
||||||
return Frame{
|
return Frame{
|
||||||
.buffer = std::move(buffer),
|
.buffer = std::move(buffer),
|
||||||
.info =
|
.info =
|
||||||
|
@ -531,9 +567,14 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
|
||||||
{
|
{
|
||||||
.video =
|
.video =
|
||||||
{
|
{
|
||||||
.width = u32(frame.width),
|
.width = u32(width),
|
||||||
.height = u32(frame.height),
|
.height = u32(height),
|
||||||
.aspect_ratio = AVRationalToF32(frame.sample_aspect_ratio),
|
.aspect_ratio = AVRationalToF32(frame.sample_aspect_ratio),
|
||||||
|
.crop_left_offset = u32(frame.crop_left),
|
||||||
|
.crop_right_offset = u32(frame.crop_right + (width - frame.width)),
|
||||||
|
.crop_top_offset = u32(frame.crop_top),
|
||||||
|
.crop_bottom_offset =
|
||||||
|
u32(frame.crop_bottom + (height - frame.height)),
|
||||||
.pitch = u32(frame.linesize[0]),
|
.pitch = u32(frame.linesize[0]),
|
||||||
.luma_bit_depth = 8,
|
.luma_bit_depth = 8,
|
||||||
.chroma_bit_depth = 8,
|
.chroma_bit_depth = 8,
|
||||||
|
@ -655,6 +696,7 @@ Frame AvPlayerSource::PrepareAudioFrame(FrameBuffer buffer, const AVFrame& frame
|
||||||
.audio =
|
.audio =
|
||||||
{
|
{
|
||||||
.channel_count = u16(frame.ch_layout.nb_channels),
|
.channel_count = u16(frame.ch_layout.nb_channels),
|
||||||
|
.sample_rate = u32(frame.sample_rate),
|
||||||
.size = u32(size),
|
.size = u32(size),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -120,17 +120,17 @@ private:
|
||||||
|
|
||||||
class AvPlayerSource {
|
class AvPlayerSource {
|
||||||
public:
|
public:
|
||||||
AvPlayerSource(AvPlayerStateCallback& state, std::string_view path,
|
AvPlayerSource(AvPlayerStateCallback& state);
|
||||||
const SceAvPlayerInitData& init_data, SceAvPlayerSourceType source_type);
|
|
||||||
~AvPlayerSource();
|
~AvPlayerSource();
|
||||||
|
|
||||||
|
bool Init(const SceAvPlayerInitData& init_data, std::string_view path);
|
||||||
bool FindStreamInfo();
|
bool FindStreamInfo();
|
||||||
s32 GetStreamCount();
|
s32 GetStreamCount();
|
||||||
s32 GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
|
bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
|
||||||
bool EnableStream(u32 stream_index);
|
bool EnableStream(u32 stream_index);
|
||||||
void SetLooping(bool is_looping);
|
void SetLooping(bool is_looping);
|
||||||
std::optional<bool> HasFrames(u32 num_frames);
|
std::optional<bool> HasFrames(u32 num_frames);
|
||||||
s32 Start();
|
bool Start();
|
||||||
bool Stop();
|
bool Stop();
|
||||||
bool GetAudioData(SceAvPlayerFrameInfo& audio_info);
|
bool GetAudioData(SceAvPlayerFrameInfo& audio_info);
|
||||||
bool GetVideoData(SceAvPlayerFrameInfo& video_info);
|
bool GetVideoData(SceAvPlayerFrameInfo& video_info);
|
||||||
|
|
|
@ -24,6 +24,7 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, s32 event_i
|
||||||
s32 timedtext_stream_index = -1;
|
s32 timedtext_stream_index = -1;
|
||||||
const s32 stream_count = self->GetStreamCount();
|
const s32 stream_count = self->GetStreamCount();
|
||||||
if (AVPLAYER_IS_ERROR(stream_count)) {
|
if (AVPLAYER_IS_ERROR(stream_count)) {
|
||||||
|
self->Stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stream_count == 0) {
|
if (stream_count == 0) {
|
||||||
|
@ -32,7 +33,10 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, s32 event_i
|
||||||
}
|
}
|
||||||
for (u32 stream_index = 0; stream_index < stream_count; ++stream_index) {
|
for (u32 stream_index = 0; stream_index < stream_count; ++stream_index) {
|
||||||
SceAvPlayerStreamInfo info{};
|
SceAvPlayerStreamInfo info{};
|
||||||
self->GetStreamInfo(stream_index, info);
|
if (!self->GetStreamInfo(stream_index, info)) {
|
||||||
|
self->Stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string_view default_language(
|
const std::string_view default_language(
|
||||||
reinterpret_cast<char*>(self->m_default_language));
|
reinterpret_cast<char*>(self->m_default_language));
|
||||||
|
@ -116,23 +120,28 @@ AvPlayerState::~AvPlayerState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called inside GAME thread
|
// Called inside GAME thread
|
||||||
s32 AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType source_type) {
|
bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType source_type) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "File path is empty.");
|
LOG_ERROR(Lib_AvPlayer, "File path is empty.");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_lock lock(m_source_mutex);
|
std::unique_lock lock(m_source_mutex);
|
||||||
if (m_up_source != nullptr) {
|
if (m_up_source != nullptr) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Only one source is supported.");
|
LOG_ERROR(Lib_AvPlayer, "Only one source is supported.");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_up_source = std::make_unique<AvPlayerSource>(*this, path, m_init_data, source_type);
|
m_up_source = std::make_unique<AvPlayerSource>(*this);
|
||||||
|
if (!m_up_source->Init(m_init_data, path)) {
|
||||||
|
SetState(AvState::Error);
|
||||||
|
m_up_source.reset();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AddSourceEvent();
|
AddSourceEvent();
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called inside GAME thread
|
// Called inside GAME thread
|
||||||
|
@ -146,25 +155,25 @@ s32 AvPlayerState::GetStreamCount() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called inside GAME thread
|
// Called inside GAME thread
|
||||||
s32 AvPlayerState::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
bool AvPlayerState::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) {
|
||||||
std::shared_lock lock(m_source_mutex);
|
std::shared_lock lock(m_source_mutex);
|
||||||
if (m_up_source == nullptr) {
|
if (m_up_source == nullptr) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info. No source.", stream_index);
|
LOG_ERROR(Lib_AvPlayer, "Could not get stream {} info. No source.", stream_index);
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
return m_up_source->GetStreamInfo(stream_index, info);
|
return m_up_source->GetStreamInfo(stream_index, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called inside GAME thread
|
// Called inside GAME thread
|
||||||
s32 AvPlayerState::Start() {
|
bool AvPlayerState::Start() {
|
||||||
std::shared_lock lock(m_source_mutex);
|
std::shared_lock lock(m_source_mutex);
|
||||||
if (m_up_source == nullptr || m_up_source->Start() < 0) {
|
if (m_up_source == nullptr || !m_up_source->Start()) {
|
||||||
LOG_ERROR(Lib_AvPlayer, "Could not start playback.");
|
LOG_ERROR(Lib_AvPlayer, "Could not start playback.");
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
SetState(AvState::Play);
|
SetState(AvState::Play);
|
||||||
OnPlaybackStateChanged(AvState::Play);
|
OnPlaybackStateChanged(AvState::Play);
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvPlayerState::AvControllerThread(std::stop_token stop) {
|
void AvPlayerState::AvControllerThread(std::stop_token stop) {
|
||||||
|
@ -219,11 +228,14 @@ bool AvPlayerState::Stop() {
|
||||||
if (m_up_source == nullptr || m_current_state == AvState::Stop) {
|
if (m_up_source == nullptr || m_current_state == AvState::Stop) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!m_up_source->Stop()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!SetState(AvState::Stop)) {
|
if (!SetState(AvState::Stop)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
OnPlaybackStateChanged(AvState::Stop);
|
OnPlaybackStateChanged(AvState::Stop);
|
||||||
return m_up_source->Stop();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AvPlayerState::GetVideoData(SceAvPlayerFrameInfo& video_info) {
|
bool AvPlayerState::GetVideoData(SceAvPlayerFrameInfo& video_info) {
|
||||||
|
|
|
@ -24,11 +24,11 @@ public:
|
||||||
AvPlayerState(const SceAvPlayerInitData& init_data);
|
AvPlayerState(const SceAvPlayerInitData& init_data);
|
||||||
~AvPlayerState();
|
~AvPlayerState();
|
||||||
|
|
||||||
s32 AddSource(std::string_view filename, SceAvPlayerSourceType source_type);
|
bool AddSource(std::string_view filename, SceAvPlayerSourceType source_type);
|
||||||
s32 GetStreamCount();
|
s32 GetStreamCount();
|
||||||
s32 GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
|
bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
|
||||||
bool EnableStream(u32 stream_index);
|
bool EnableStream(u32 stream_index);
|
||||||
s32 Start();
|
bool Start();
|
||||||
bool Stop();
|
bool Stop();
|
||||||
bool GetAudioData(SceAvPlayerFrameInfo& audio_info);
|
bool GetAudioData(SceAvPlayerFrameInfo& audio_info);
|
||||||
bool GetVideoData(SceAvPlayerFrameInfo& video_info);
|
bool GetVideoData(SceAvPlayerFrameInfo& video_info);
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// Generated By moduleGenerator
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
|
@ -233,9 +233,6 @@ constexpr int SCE_KERNEL_ERROR_ESDKVERSION = 0x80020063;
|
||||||
constexpr int SCE_KERNEL_ERROR_ESTART = 0x80020064;
|
constexpr int SCE_KERNEL_ERROR_ESTART = 0x80020064;
|
||||||
constexpr int SCE_KERNEL_ERROR_ESTOP = 0x80020065;
|
constexpr int SCE_KERNEL_ERROR_ESTOP = 0x80020065;
|
||||||
|
|
||||||
// libSceRandom error codes
|
|
||||||
constexpr int SCE_RANDOM_ERROR_INVALID = 0x817C0016;
|
|
||||||
|
|
||||||
// videoOut
|
// videoOut
|
||||||
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument
|
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument
|
||||||
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; // invalid addresses
|
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; // invalid addresses
|
||||||
|
@ -249,14 +246,6 @@ constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot alr
|
||||||
constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full
|
constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full
|
||||||
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option
|
constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option
|
||||||
|
|
||||||
// GnmDriver
|
|
||||||
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID = 0x80D17000;
|
|
||||||
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID = 0x80D17001;
|
|
||||||
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR = 0x80D17003;
|
|
||||||
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE = 0x80D17002;
|
|
||||||
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR = 0x80D17004;
|
|
||||||
constexpr int ORBIS_GNM_ERROR_FAILURE = 0x8EEE00FF;
|
|
||||||
|
|
||||||
// Generic
|
// Generic
|
||||||
constexpr int ORBIS_OK = 0x00000000;
|
constexpr int ORBIS_OK = 0x00000000;
|
||||||
constexpr int ORBIS_FAIL = 0xFFFFFFFF;
|
constexpr int ORBIS_FAIL = 0xFFFFFFFF;
|
||||||
|
@ -472,3 +461,5 @@ constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF;
|
||||||
|
|
||||||
// AppContent library
|
// AppContent library
|
||||||
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002;
|
||||||
|
constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007;
|
||||||
|
constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005;
|
|
@ -0,0 +1,85 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_FAILED_INVALID_ARGUMENT = 0x80D11000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_NOT_ENOUGH_RESOURCES = 0x80D11001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_INVALID_COMMAND_BUFFER = 0x80D11080;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_INVALID_QUEUE_FULL = 0x80D11081;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_REQUEST_FAILED = 0x80D11082;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_SUBMISSION_FAILED_INTERNAL_ERROR = 0x80D110FF;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING = 0x80D12000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_RWBUFFER_ROTYPE = 0x80D12001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_BLENDING = 0x80D12002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_DRAW_CU_MASK = 0x80D12003;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_MRT_SETUP = 0x80D12004;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_DEPTH_RT_SETUP = 0x80D12005;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WARNING_PS_AND_MRT_FORMAT = 0x80D1200F;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_ERROR = 0x80D13000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_VSHARP = 0x80D13001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_TSHARP = 0x80D13002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_RESOURCE = 0x80D13003;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_TABLE_MEMORY = 0x80D13004;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_WRITE_EVENT_OP = 0x80D13005;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_INDEX_BUFFER = 0x80D13006;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_TESS_FACTOR_BUFFER = 0x80D13007;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_SCRATCH_RING = 0x80D13008;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_PRIMITIVE_TYPE = 0x80D13009;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_INDEX_SIZE = 0x80D1300A;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_INLINE_DRAW_SIZE = 0x80D1300B;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_NUM_INPUT_PATCHES = 0x80D1300C;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_GS_MODE = 0x80D1300D;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_SHADER_ADDRESS = 0x80D1300E;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_BORDER_COLOR_TABLE = 0x80D1300F;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_SSHARP = 0x80D13010;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_DISPATCH_DRAW = 0x80D13011;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_ACTIVE_SHADER_STAGE = 0x80D13012;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_DCB = 0x80D13013;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_MISMATCH_SHADER_STAGE = 0x80D13014;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_MRT_SETUP = 0x80D13015;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_BAD_OP_CODE = 0x80D13016;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_DEPTH_RT_SETUP = 0x80D13017;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_NUM_INSTANCES = 0x80D13018;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_SRT = 0x80D13019;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_INVALID_ARGUMENT = 0x80D13FFD;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_FAILED_INTERNAL_ERROR = 0x80D13FFE;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_VALIDATION_NOT_ENABLED = 0x80D13FFF;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_CAPTURE_FILE_IO = 0x80D15000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_CAPTURE_RAZOR_NOT_LOADED = 0x80D15001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_CAPTURE_NOTHING_TO_CAPTURE = 0x80D15002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_CAPTURE_FAILED_INTERNAL = 0x80D1500F;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_ID = 0x80D17000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_QUEUE_ID = 0x80D17001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_SIZE = 0x80D17002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_RING_BASE_ADDR = 0x80D17003;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_READ_PTR_ADDR = 0x80D17004;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INVALID_PIPE_PRIORITY = 0x80D17005;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_COMPUTEQUEUE_INTERNAL = 0x80D170FF;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_ARGUMENT = 0x80D19000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_SHADER = 0x80D19001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_STALE_HANDLE = 0x80D19002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_FULL = 0x80D19003;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_NOT_PERMITTED = 0x80D19004;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OUTPUT_ARGUMENT_IS_NULL = 0x80D19005;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OWNER_HANDLE_INVALID = 0x80D19006;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_HANDLE_INVALID = 0x80D19007;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_TYPE_INVALID = 0x80D19008;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_GDS_RESOURCE_TYPE_INVALID = 0x80D19009;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_SIZE_INVALID = 0x80D1900A;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_ADDRESS_IS_NULL = 0x80D1900B;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_GDS_OFFSET_INVALID = 0x80D1900C;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_NAME_IS_NULL = 0x80D1900D;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_OWNER_NAME_IS_NULL = 0x80D1900E;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_FIND_CALLBACK_IS_NULL = 0x80D1900F;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_RESOURCE_IS_NOT_SHADER = 0x80D19010;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_USER_MEMORY_PARAM_IS_NULL = 0x80D19011;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_USER_MEMORY_PARAM_NOT_ALIGNED = 0x80D19012;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_NAME_LENGTH_PARAM = 0x80D19013;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_SIZE_PARAM = 0x80D19014;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INVALID_NUM_RESOURCES_PARAM = 0x80D19015;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_RESOURCE_REGISTRATION_INTERNAL = 0x80D19FFF;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_PARAMETER_NULL = 0x80D1B000;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_FAILED = 0x80D1B001;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_GET_GPU_INFO_PARAMETER_INVALID = 0x80D1B002;
|
||||||
|
constexpr int ORBIS_GNM_ERROR_FAILURE = 0x8EEE00FF;
|
|
@ -1,6 +1,9 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "gnm_error.h"
|
||||||
|
#include "gnmdriver.h"
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
@ -9,7 +12,6 @@
|
||||||
#include "common/slot_vector.h"
|
#include "common/slot_vector.h"
|
||||||
#include "core/address_space.h"
|
#include "core/address_space.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/gnmdriver/gnmdriver.h"
|
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/videoout/video_out.h"
|
#include "core/libraries/videoout/video_out.h"
|
||||||
|
@ -55,6 +57,10 @@ static constexpr auto HwInitPacketSize = 0x100u;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static constexpr std::array InitSequence{
|
static constexpr std::array InitSequence{
|
||||||
|
// A fake preamble to mimic context reset sent by FW
|
||||||
|
0xc0001200u, 0u, // IT_CLEAR_STATE
|
||||||
|
|
||||||
|
// Actual init state sequence
|
||||||
0xc0017600u, 0x216u, 0xffffffffu,
|
0xc0017600u, 0x216u, 0xffffffffu,
|
||||||
0xc0017600u, 0x217u, 0xffffffffu,
|
0xc0017600u, 0x217u, 0xffffffffu,
|
||||||
0xc0017600u, 0x215u, 0u,
|
0xc0017600u, 0x215u, 0u,
|
||||||
|
@ -94,9 +100,13 @@ static constexpr std::array InitSequence{
|
||||||
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
||||||
0xc0017900u, 0x200u, 0xe0000000u,
|
0xc0017900u, 0x200u, 0xe0000000u,
|
||||||
};
|
};
|
||||||
static_assert(InitSequence.size() == 0x73);
|
static_assert(InitSequence.size() == 0x73 + 2);
|
||||||
|
|
||||||
static constexpr std::array InitSequence175{
|
static constexpr std::array InitSequence175{
|
||||||
|
// A fake preamble to mimic context reset sent by FW
|
||||||
|
0xc0001200u, 0u, // IT_CLEAR_STATE
|
||||||
|
|
||||||
|
// Actual init state sequence
|
||||||
0xc0017600u, 0x216u, 0xffffffffu,
|
0xc0017600u, 0x216u, 0xffffffffu,
|
||||||
0xc0017600u, 0x217u, 0xffffffffu,
|
0xc0017600u, 0x217u, 0xffffffffu,
|
||||||
0xc0017600u, 0x215u, 0u,
|
0xc0017600u, 0x215u, 0u,
|
||||||
|
@ -136,9 +146,13 @@ static constexpr std::array InitSequence175{
|
||||||
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
||||||
0xc0017900u, 0x200u, 0xe0000000u,
|
0xc0017900u, 0x200u, 0xe0000000u,
|
||||||
};
|
};
|
||||||
static_assert(InitSequence175.size() == 0x73);
|
static_assert(InitSequence175.size() == 0x73 + 2);
|
||||||
|
|
||||||
static constexpr std::array InitSequence200{
|
static constexpr std::array InitSequence200{
|
||||||
|
// A fake preamble to mimic context reset sent by FW
|
||||||
|
0xc0001200u, 0u, // IT_CLEAR_STATE
|
||||||
|
|
||||||
|
// Actual init state sequence
|
||||||
0xc0017600u, 0x216u, 0xffffffffu,
|
0xc0017600u, 0x216u, 0xffffffffu,
|
||||||
0xc0017600u, 0x217u, 0xffffffffu,
|
0xc0017600u, 0x217u, 0xffffffffu,
|
||||||
0xc0017600u, 0x215u, 0u,
|
0xc0017600u, 0x215u, 0u,
|
||||||
|
@ -179,9 +193,13 @@ static constexpr std::array InitSequence200{
|
||||||
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
|
||||||
0xc0017900u, 0x200u, 0xe0000000u,
|
0xc0017900u, 0x200u, 0xe0000000u,
|
||||||
};
|
};
|
||||||
static_assert(InitSequence200.size() == 0x76);
|
static_assert(InitSequence200.size() == 0x76 + 2);
|
||||||
|
|
||||||
static constexpr std::array InitSequence350{
|
static constexpr std::array InitSequence350{
|
||||||
|
// A fake preamble to mimic context reset sent by FW
|
||||||
|
0xc0001200u, 0u, // IT_CLEAR_STATE
|
||||||
|
|
||||||
|
// Actual init state sequence
|
||||||
0xc0017600u, 0x216u, 0xffffffffu,
|
0xc0017600u, 0x216u, 0xffffffffu,
|
||||||
0xc0017600u, 0x217u, 0xffffffffu,
|
0xc0017600u, 0x217u, 0xffffffffu,
|
||||||
0xc0017600u, 0x215u, 0u,
|
0xc0017600u, 0x215u, 0u,
|
||||||
|
@ -224,7 +242,7 @@ static constexpr std::array InitSequence350{
|
||||||
0xc0017900u, 0x200u, 0xe0000000u,
|
0xc0017900u, 0x200u, 0xe0000000u,
|
||||||
0xc0016900u, 0x2aau, 0xffu,
|
0xc0016900u, 0x2aau, 0xffu,
|
||||||
};
|
};
|
||||||
static_assert(InitSequence350.size() == 0x7c);
|
static_assert(InitSequence350.size() == 0x7c + 2);
|
||||||
|
|
||||||
static constexpr std::array CtxInitSequence{
|
static constexpr std::array CtxInitSequence{
|
||||||
0xc0012800u, 0x80000000u, 0x80000000u,
|
0xc0012800u, 0x80000000u, 0x80000000u,
|
||||||
|
@ -632,12 +650,12 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
||||||
u32 flags) {
|
u32 flags) {
|
||||||
LOG_TRACE(Lib_GnmDriver, "called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||||
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) {
|
||||||
|
|
||||||
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexIndirect>(
|
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndexIndirect>(
|
||||||
|
@ -647,7 +665,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset,
|
||||||
|
|
||||||
cmdbuf[0] = data_offset;
|
cmdbuf[0] = data_offset;
|
||||||
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
cmdbuf[3] = 0;
|
cmdbuf[3] = 0;
|
||||||
|
|
||||||
cmdbuf += 4;
|
cmdbuf += 4;
|
||||||
|
@ -689,11 +707,11 @@ s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags) {
|
u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags) {
|
||||||
LOG_TRACE(Lib_GnmDriver, "called");
|
LOG_TRACE(Lib_GnmDriver, "called");
|
||||||
|
|
||||||
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
if (cmdbuf && (size == 9) && (shader_stage < ShaderStages::Max) &&
|
||||||
(vertex_sgpr_offset < 0x10u) && (instance_vgpr_offset < 0x10u)) {
|
(vertex_sgpr_offset < 0x10u) && (instance_sgpr_offset < 0x10u)) {
|
||||||
|
|
||||||
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
const auto predicate = flags & 1 ? PM4Predicate::PredEnable : PM4Predicate::PredDisable;
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndirect>(cmdbuf, 4, PM4ShaderType::ShaderGraphics,
|
cmdbuf = WriteHeader<PM4ItOpcode::DrawIndirect>(cmdbuf, 4, PM4ShaderType::ShaderGraphics,
|
||||||
|
@ -703,7 +721,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32
|
||||||
|
|
||||||
cmdbuf[0] = data_offset;
|
cmdbuf[0] = data_offset;
|
||||||
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
cmdbuf[1] = vertex_sgpr_offset == 0 ? 0 : (vertex_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
|
cmdbuf[2] = instance_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset;
|
||||||
cmdbuf[3] = 2; // auto index
|
cmdbuf[3] = 2; // auto index
|
||||||
|
|
||||||
cmdbuf += 4;
|
cmdbuf += 4;
|
||||||
|
@ -735,11 +753,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
|
||||||
cmdbuf = ClearContextState(cmdbuf);
|
cmdbuf = ClearContextState(cmdbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(cmdbuf, InitSequence.data(), InitSequence.size() * 4);
|
std::memcpy(cmdbuf, &InitSequence[2], (InitSequence.size() - 2) * 4);
|
||||||
cmdbuf += InitSequence.size();
|
cmdbuf += InitSequence.size() - 2;
|
||||||
|
|
||||||
const auto cmdbuf_left =
|
const auto cmdbuf_left =
|
||||||
HwInitPacketSize - InitSequence.size() - (clear_state ? 0xc : 0) - 1;
|
HwInitPacketSize - (InitSequence.size() - 2) - (clear_state ? 0xc : 0) - 1;
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
||||||
cmdbuf = WriteBody(cmdbuf, 0u);
|
cmdbuf = WriteBody(cmdbuf, 0u);
|
||||||
|
|
||||||
|
@ -757,10 +775,10 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdbuf = ClearContextState(cmdbuf);
|
cmdbuf = ClearContextState(cmdbuf);
|
||||||
std::memcpy(cmdbuf, InitSequence175.data(), InitSequence175.size() * 4);
|
std::memcpy(cmdbuf, &InitSequence175[2], (InitSequence175.size() - 2) * 4);
|
||||||
cmdbuf += InitSequence175.size();
|
cmdbuf += InitSequence175.size() - 2;
|
||||||
|
|
||||||
constexpr auto cmdbuf_left = HwInitPacketSize - InitSequence175.size() - 0xc - 1;
|
constexpr auto cmdbuf_left = HwInitPacketSize - (InitSequence175.size() - 2) - 0xc - 1;
|
||||||
WriteTrailingNop<cmdbuf_left>(cmdbuf);
|
WriteTrailingNop<cmdbuf_left>(cmdbuf);
|
||||||
|
|
||||||
return HwInitPacketSize;
|
return HwInitPacketSize;
|
||||||
|
@ -778,11 +796,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
|
||||||
cmdbuf = ClearContextState(cmdbuf);
|
cmdbuf = ClearContextState(cmdbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(cmdbuf, InitSequence200.data(), InitSequence200.size() * 4);
|
std::memcpy(cmdbuf, &InitSequence200[2], (InitSequence200.size() - 2) * 4);
|
||||||
cmdbuf += InitSequence200.size();
|
cmdbuf += InitSequence200.size() - 2;
|
||||||
|
|
||||||
const auto cmdbuf_left =
|
const auto cmdbuf_left =
|
||||||
HwInitPacketSize - InitSequence200.size() - (clear_state ? 0xc : 0) - 1;
|
HwInitPacketSize - (InitSequence200.size() - 2) - (clear_state ? 0xc : 0) - 1;
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
||||||
cmdbuf = WriteBody(cmdbuf, 0u);
|
cmdbuf = WriteBody(cmdbuf, 0u);
|
||||||
|
|
||||||
|
@ -804,11 +822,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
|
||||||
cmdbuf = ClearContextState(cmdbuf);
|
cmdbuf = ClearContextState(cmdbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(cmdbuf, InitSequence350.data(), InitSequence350.size() * 4);
|
std::memcpy(cmdbuf, &InitSequence350[2], (InitSequence350.size() - 2) * 4);
|
||||||
cmdbuf += InitSequence350.size();
|
cmdbuf += InitSequence350.size() - 2;
|
||||||
|
|
||||||
const auto cmdbuf_left =
|
const auto cmdbuf_left =
|
||||||
HwInitPacketSize - InitSequence350.size() - (clear_state ? 0xc : 0) - 1;
|
HwInitPacketSize - (InitSequence350.size() - 2) - (clear_state ? 0xc : 0) - 1;
|
||||||
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
|
||||||
cmdbuf = WriteBody(cmdbuf, 0u);
|
cmdbuf = WriteBody(cmdbuf, 0u);
|
||||||
|
|
||||||
|
@ -1743,7 +1761,7 @@ s32 PS4_SYSV_ABI sceGnmSetVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, u3
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f | shader_modifier);
|
const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f) | shader_modifier;
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS
|
||||||
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
|
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
|
||||||
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL
|
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL
|
||||||
|
|
|
@ -45,7 +45,7 @@ s32 PS4_SYSV_ABI sceGnmDrawIndex(u32* cmdbuf, u32 size, u32 index_count, uintptr
|
||||||
u32 flags, u32 type);
|
u32 flags, u32 type);
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags);
|
s32 PS4_SYSV_ABI sceGnmDrawIndexAuto(u32* cmdbuf, u32 size, u32 index_count, u32 flags);
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
s32 PS4_SYSV_ABI sceGnmDrawIndexIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset,
|
u32 vertex_sgpr_offset, u32 instance_sgpr_offset,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectCountMulti();
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndexIndirectMulti();
|
||||||
|
@ -53,7 +53,7 @@ int PS4_SYSV_ABI sceGnmDrawIndexMultiInstanced();
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count,
|
s32 PS4_SYSV_ABI sceGnmDrawIndexOffset(u32* cmdbuf, u32 size, u32 index_offset, u32 index_count,
|
||||||
u32 flags);
|
u32 flags);
|
||||||
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
s32 PS4_SYSV_ABI sceGnmDrawIndirect(u32* cmdbuf, u32 size, u32 data_offset, u32 shader_stage,
|
||||||
u32 vertex_sgpr_offset, u32 instance_vgpr_offset, u32 flags);
|
u32 vertex_sgpr_offset, u32 instance_sgpr_offset, u32 flags);
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndirectCountMulti();
|
||||||
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
int PS4_SYSV_ABI sceGnmDrawIndirectMulti();
|
||||||
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size);
|
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <common/assert.h>
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "event_flag_obj.h"
|
#include "event_flag_obj.h"
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/libraries/kernel/event_queue.h"
|
#include "core/libraries/kernel/event_queue.h"
|
||||||
|
|
||||||
|
|
|
@ -538,7 +538,7 @@ void fileSystemSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
|
||||||
// openOrbis (to check if it is valid out of OpenOrbis
|
// openOrbis (to check if it is valid out of OpenOrbis
|
||||||
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("6c3rCVE-fTU", "libkernel", 1, "libkernel", 1, 1,
|
||||||
posix_open); // _open shoudld be equal to open function
|
posix_open); // _open should be equal to open function
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <bit>
|
#include <bit>
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
@ -15,7 +16,8 @@ namespace Libraries::Kernel {
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
|
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
|
||||||
LOG_WARNING(Kernel_Vmm, "called");
|
LOG_WARNING(Kernel_Vmm, "called");
|
||||||
return SCE_KERNEL_MAIN_DMEM_SIZE;
|
const auto* memory = Core::Memory::Instance();
|
||||||
|
return memory->GetTotalDirectSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u64 len,
|
||||||
|
@ -52,8 +54,8 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType,
|
s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType,
|
||||||
s64* physAddrOut) {
|
s64* physAddrOut) {
|
||||||
return sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, len, alignment, memoryType,
|
const auto searchEnd = static_cast<s64>(sceKernelGetDirectMemorySize());
|
||||||
physAddrOut);
|
return sceKernelAllocateDirectMemory(0, searchEnd, len, alignment, memoryType, physAddrOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len) {
|
s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len) {
|
||||||
|
@ -75,19 +77,28 @@ s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchE
|
||||||
LOG_WARNING(Kernel_Vmm, "called searchStart = {:#x}, searchEnd = {:#x}, alignment = {:#x}",
|
LOG_WARNING(Kernel_Vmm, "called searchStart = {:#x}, searchEnd = {:#x}, alignment = {:#x}",
|
||||||
searchStart, searchEnd, alignment);
|
searchStart, searchEnd, alignment);
|
||||||
|
|
||||||
if (searchEnd <= searchStart) {
|
if (physAddrOut == nullptr || sizeOut == nullptr) {
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
if (searchEnd > SCE_KERNEL_MAIN_DMEM_SIZE) {
|
if (searchEnd > sceKernelGetDirectMemorySize()) {
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
if (searchEnd <= searchStart) {
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
auto* memory = Core::Memory::Instance();
|
auto* memory = Core::Memory::Instance();
|
||||||
|
|
||||||
PAddr physAddr;
|
PAddr physAddr{};
|
||||||
s32 result =
|
size_t size{};
|
||||||
memory->DirectQueryAvailable(searchStart, searchEnd, alignment, &physAddr, sizeOut);
|
s32 result = memory->DirectQueryAvailable(searchStart, searchEnd, alignment, &physAddr, &size);
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
*physAddrOut = static_cast<u64>(physAddr);
|
*physAddrOut = static_cast<u64>(physAddr);
|
||||||
|
*sizeOut = size;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -245,46 +256,56 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len);
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEntries,
|
s32 PS4_SYSV_ABI sceKernelBatchMap2(OrbisKernelBatchMapEntry* entries, int numEntries,
|
||||||
int* numEntriesOut, int flags) {
|
int* numEntriesOut, int flags) {
|
||||||
|
int result = ORBIS_OK;
|
||||||
int processed = 0;
|
int processed = 0;
|
||||||
int result = 0;
|
for (int i = 0; i < numEntries; i++, processed++) {
|
||||||
for (int i = 0; i < numEntries; i++) {
|
|
||||||
if (entries == nullptr || entries[i].length == 0 || entries[i].operation > 4) {
|
if (entries == nullptr || entries[i].length == 0 || entries[i].operation > 4) {
|
||||||
result = ORBIS_KERNEL_ERROR_EINVAL;
|
result = ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
break; // break and assign a value to numEntriesOut.
|
break; // break and assign a value to numEntriesOut.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_DIRECT) {
|
switch (entries[i].operation) {
|
||||||
|
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_DIRECT: {
|
||||||
result = sceKernelMapNamedDirectMemory(&entries[i].start, entries[i].length,
|
result = sceKernelMapNamedDirectMemory(&entries[i].start, entries[i].length,
|
||||||
entries[i].protection, flags,
|
entries[i].protection, flags,
|
||||||
static_cast<s64>(entries[i].offset), 0, "");
|
static_cast<s64>(entries[i].offset), 0, "");
|
||||||
LOG_INFO(
|
LOG_INFO(Kernel_Vmm,
|
||||||
Kernel_Vmm,
|
"entry = {}, operation = {}, len = {:#x}, offset = {:#x}, type = {}, "
|
||||||
"BatchMap: entry = {}, operation = {}, len = {:#x}, offset = {:#x}, type = {}, "
|
|
||||||
"result = {}",
|
"result = {}",
|
||||||
i, entries[i].operation, entries[i].length, entries[i].offset, (u8)entries[i].type,
|
i, entries[i].operation, entries[i].length, entries[i].offset,
|
||||||
result);
|
(u8)entries[i].type, result);
|
||||||
|
break;
|
||||||
if (result == 0)
|
}
|
||||||
processed++;
|
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_UNMAP: {
|
||||||
} else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_UNMAP) {
|
|
||||||
result = sceKernelMunmap(entries[i].start, entries[i].length);
|
result = sceKernelMunmap(entries[i].start, entries[i].length);
|
||||||
LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}",
|
LOG_INFO(Kernel_Vmm, "entry = {}, operation = {}, len = {:#x}, result = {}", i,
|
||||||
i, entries[i].operation, entries[i].length, result);
|
entries[i].operation, entries[i].length, result);
|
||||||
|
break;
|
||||||
if (result == 0)
|
}
|
||||||
processed++;
|
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE: {
|
||||||
} else if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE) {
|
|
||||||
result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length,
|
result = sceKernelMapNamedFlexibleMemory(&entries[i].start, entries[i].length,
|
||||||
entries[i].protection, flags, "");
|
entries[i].protection, flags, "");
|
||||||
LOG_INFO(Kernel_Vmm,
|
LOG_INFO(Kernel_Vmm,
|
||||||
"BatchMap: entry = {}, operation = {}, len = {:#x}, type = {}, "
|
"entry = {}, operation = {}, len = {:#x}, type = {}, "
|
||||||
"result = {}",
|
"result = {}",
|
||||||
i, entries[i].operation, entries[i].length, (u8)entries[i].type, result);
|
i, entries[i].operation, entries[i].length, (u8)entries[i].type, result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_TYPE_PROTECT: {
|
||||||
|
// By now, ignore protection and log it instead
|
||||||
|
LOG_WARNING(Kernel_Vmm,
|
||||||
|
"entry = {}, operation = {}, len = {:#x}, type = {} "
|
||||||
|
"is UNSUPPORTED and skipped",
|
||||||
|
i, entries[i].operation, entries[i].length, (u8)entries[i].type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result == 0)
|
if (result != ORBIS_OK) {
|
||||||
processed++;
|
break;
|
||||||
} else {
|
|
||||||
UNREACHABLE_MSG("called: Unimplemented Operation = {}", entries[i].operation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (numEntriesOut != NULL) { // can be zero. do not return an error code.
|
if (numEntriesOut != NULL) { // can be zero. do not return an error code.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 6_GB; // ~ 6GB
|
constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5056_MB; // ~ 5GB
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
|
|
|
@ -2,14 +2,16 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <semaphore>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <semaphore.h>
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/error.h"
|
#include "common/error.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
|
#include "core/cpu_patches.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/libkernel.h"
|
#include "core/libraries/kernel/libkernel.h"
|
||||||
#include "core/libraries/kernel/thread_management.h"
|
#include "core/libraries/kernel/thread_management.h"
|
||||||
|
@ -510,23 +512,24 @@ int PS4_SYSV_ABI scePthreadMutexattrInit(ScePthreadMutexattr* attr) {
|
||||||
int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) {
|
int PS4_SYSV_ABI scePthreadMutexattrSettype(ScePthreadMutexattr* attr, int type) {
|
||||||
int ptype = PTHREAD_MUTEX_DEFAULT;
|
int ptype = PTHREAD_MUTEX_DEFAULT;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 1:
|
case ORBIS_PTHREAD_MUTEX_ERRORCHECK:
|
||||||
ptype = PTHREAD_MUTEX_ERRORCHECK;
|
ptype = PTHREAD_MUTEX_ERRORCHECK;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case ORBIS_PTHREAD_MUTEX_RECURSIVE:
|
||||||
ptype = PTHREAD_MUTEX_RECURSIVE;
|
ptype = PTHREAD_MUTEX_RECURSIVE;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case ORBIS_PTHREAD_MUTEX_NORMAL:
|
||||||
case 4:
|
case ORBIS_PTHREAD_MUTEX_ADAPTIVE:
|
||||||
ptype = PTHREAD_MUTEX_NORMAL;
|
ptype = PTHREAD_MUTEX_NORMAL;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Invalid type: {}", type);
|
return SCE_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype);
|
int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype);
|
||||||
|
ASSERT(result == 0);
|
||||||
|
|
||||||
return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
|
return SCE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol) {
|
int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol) {
|
||||||
|
@ -984,6 +987,7 @@ static void cleanup_thread(void* arg) {
|
||||||
destructor(value);
|
destructor(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Core::CleanupThreadPatchStack();
|
||||||
thread->is_almost_done = true;
|
thread->is_almost_done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -991,6 +995,7 @@ static void* run_thread(void* arg) {
|
||||||
auto* thread = static_cast<ScePthread>(arg);
|
auto* thread = static_cast<ScePthread>(arg);
|
||||||
Common::SetCurrentThreadName(thread->name.c_str());
|
Common::SetCurrentThreadName(thread->name.c_str());
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
||||||
|
Core::InitializeThreadPatchStack();
|
||||||
linker->InitTlsForThread(false);
|
linker->InitTlsForThread(false);
|
||||||
void* ret = nullptr;
|
void* ret = nullptr;
|
||||||
g_pthread_self = thread;
|
g_pthread_self = thread;
|
||||||
|
@ -1123,7 +1128,6 @@ int PS4_SYSV_ABI posix_pthread_join(ScePthread thread, void** res) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
|
int PS4_SYSV_ABI scePthreadDetach(ScePthread thread) {
|
||||||
LOG_INFO(Kernel_Pthread, "thread create name = {}", thread->name);
|
|
||||||
thread->is_detached = true;
|
thread->is_detached = true;
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1374,90 +1378,97 @@ int PS4_SYSV_ABI posix_pthread_detach(ScePthread thread) {
|
||||||
return pthread_detach(thread->pth);
|
return pthread_detach(thread->pth);
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_sem_init(sem_t* sem, int pshared, unsigned int value) {
|
int PS4_SYSV_ABI posix_sem_init(PthreadSemInternal** sem, int pshared, unsigned int value) {
|
||||||
int result = sem_init(sem, pshared, value);
|
if (value > ORBIS_KERNEL_SEM_VALUE_MAX) {
|
||||||
if (result == -1) {
|
SetPosixErrno(EINVAL);
|
||||||
SetPosixErrno(errno);
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
if (sem != nullptr) {
|
||||||
|
*sem = new PthreadSemInternal{
|
||||||
|
.semaphore = std::counting_semaphore<ORBIS_KERNEL_SEM_VALUE_MAX>{value},
|
||||||
|
.value = {static_cast<int>(value)},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) {
|
int PS4_SYSV_ABI posix_sem_wait(PthreadSemInternal** sem) {
|
||||||
int result = sem_wait(sem);
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
if (result == -1) {
|
SetPosixErrno(EINVAL);
|
||||||
SetPosixErrno(errno);
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
(*sem)->semaphore.acquire();
|
||||||
|
--(*sem)->value;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_sem_trywait(sem_t* sem) {
|
int PS4_SYSV_ABI posix_sem_trywait(PthreadSemInternal** sem) {
|
||||||
int result = sem_trywait(sem);
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
if (result == -1) {
|
SetPosixErrno(EINVAL);
|
||||||
SetPosixErrno(errno);
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
if (!(*sem)->semaphore.try_acquire()) {
|
||||||
|
SetPosixErrno(EAGAIN);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
--(*sem)->value;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_SEM_TIMEDWAIT
|
int PS4_SYSV_ABI posix_sem_timedwait(PthreadSemInternal** sem, const timespec* t) {
|
||||||
int sem_timedwait(sem_t* sem, const struct timespec* abstime) {
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
int rc;
|
SetPosixErrno(EINVAL);
|
||||||
while ((rc = sem_trywait(sem)) == EAGAIN) {
|
return -1;
|
||||||
struct timespec curr_time;
|
|
||||||
clock_gettime(CLOCK_REALTIME, &curr_time);
|
|
||||||
|
|
||||||
s64 remaining_ns = 0;
|
|
||||||
remaining_ns +=
|
|
||||||
(static_cast<s64>(abstime->tv_sec) - static_cast<s64>(curr_time.tv_sec)) * 1000000000L;
|
|
||||||
remaining_ns += static_cast<s64>(abstime->tv_nsec) - static_cast<s64>(curr_time.tv_nsec);
|
|
||||||
|
|
||||||
if (remaining_ns <= 0) {
|
|
||||||
return ETIMEDOUT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timespec sleep_time;
|
using std::chrono::duration_cast;
|
||||||
sleep_time.tv_sec = 0;
|
using std::chrono::nanoseconds;
|
||||||
if (remaining_ns < 5000000L) {
|
using std::chrono::seconds;
|
||||||
sleep_time.tv_nsec = remaining_ns;
|
using std::chrono::system_clock;
|
||||||
} else {
|
|
||||||
sleep_time.tv_nsec = 5000000;
|
const system_clock::time_point time{
|
||||||
|
duration_cast<system_clock::duration>(seconds{t->tv_sec} + nanoseconds{t->tv_nsec})};
|
||||||
|
if (!(*sem)->semaphore.try_acquire_until(time)) {
|
||||||
|
SetPosixErrno(ETIMEDOUT);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
--(*sem)->value;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nanosleep(&sleep_time, nullptr);
|
int PS4_SYSV_ABI posix_sem_post(PthreadSemInternal** sem) {
|
||||||
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
|
SetPosixErrno(EINVAL);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return rc;
|
if ((*sem)->value == ORBIS_KERNEL_SEM_VALUE_MAX) {
|
||||||
|
SetPosixErrno(EOVERFLOW);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
++(*sem)->value;
|
||||||
|
(*sem)->semaphore.release();
|
||||||
int PS4_SYSV_ABI posix_sem_timedwait(sem_t* sem, const timespec* t) {
|
return 0;
|
||||||
int result = sem_timedwait(sem, t);
|
|
||||||
if (result == -1) {
|
|
||||||
SetPosixErrno(errno);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_sem_post(sem_t* sem) {
|
int PS4_SYSV_ABI posix_sem_destroy(PthreadSemInternal** sem) {
|
||||||
int result = sem_post(sem);
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
if (result == -1) {
|
SetPosixErrno(EINVAL);
|
||||||
SetPosixErrno(errno);
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
delete *sem;
|
||||||
|
*sem = nullptr;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_sem_destroy(sem_t* sem) {
|
int PS4_SYSV_ABI posix_sem_getvalue(PthreadSemInternal** sem, int* sval) {
|
||||||
int result = sem_destroy(sem);
|
if (sem == nullptr || *sem == nullptr) {
|
||||||
if (result == -1) {
|
SetPosixErrno(EINVAL);
|
||||||
SetPosixErrno(errno);
|
return -1;
|
||||||
}
|
}
|
||||||
return result;
|
if (sval) {
|
||||||
|
*sval = (*sem)->value;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
int PS4_SYSV_ABI posix_sem_getvalue(sem_t* sem, int* sval) {
|
|
||||||
int result = sem_getvalue(sem, sval);
|
|
||||||
if (result == -1) {
|
|
||||||
SetPosixErrno(errno);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI posix_pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* size) {
|
int PS4_SYSV_ABI posix_pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* size) {
|
||||||
|
|
|
@ -5,10 +5,12 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <semaphore>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
|
@ -19,6 +21,12 @@ namespace Libraries::Kernel {
|
||||||
constexpr int ORBIS_KERNEL_PRIO_FIFO_DEFAULT = 700;
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_DEFAULT = 700;
|
||||||
constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 256;
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_HIGHEST = 256;
|
||||||
constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 767;
|
constexpr int ORBIS_KERNEL_PRIO_FIFO_LOWEST = 767;
|
||||||
|
constexpr int ORBIS_KERNEL_SEM_VALUE_MAX = 0x7FFFFFFF;
|
||||||
|
|
||||||
|
constexpr int ORBIS_PTHREAD_MUTEX_ERRORCHECK = 1;
|
||||||
|
constexpr int ORBIS_PTHREAD_MUTEX_RECURSIVE = 2;
|
||||||
|
constexpr int ORBIS_PTHREAD_MUTEX_NORMAL = 3;
|
||||||
|
constexpr int ORBIS_PTHREAD_MUTEX_ADAPTIVE = 4;
|
||||||
|
|
||||||
struct PthreadInternal;
|
struct PthreadInternal;
|
||||||
struct PthreadAttrInternal;
|
struct PthreadAttrInternal;
|
||||||
|
@ -104,6 +112,11 @@ struct PthreadRwInternal {
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct PthreadSemInternal {
|
||||||
|
std::counting_semaphore<ORBIS_KERNEL_SEM_VALUE_MAX> semaphore;
|
||||||
|
std::atomic<s32> value;
|
||||||
|
};
|
||||||
|
|
||||||
class PThreadPool {
|
class PThreadPool {
|
||||||
public:
|
public:
|
||||||
ScePthread Create();
|
ScePthread Create();
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <list>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <utility>
|
|
||||||
#include <boost/intrusive/list.hpp>
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
|
@ -13,9 +13,6 @@
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
using ListBaseHook =
|
|
||||||
boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>>;
|
|
||||||
|
|
||||||
class Semaphore {
|
class Semaphore {
|
||||||
public:
|
public:
|
||||||
Semaphore(s32 init_count, s32 max_count, std::string_view name, bool is_fifo)
|
Semaphore(s32 init_count, s32 max_count, std::string_view name, bool is_fifo)
|
||||||
|
@ -37,7 +34,7 @@ public:
|
||||||
|
|
||||||
// Create waiting thread object and add it into the list of waiters.
|
// Create waiting thread object and add it into the list of waiters.
|
||||||
WaitingThread waiter{need_count, is_fifo};
|
WaitingThread waiter{need_count, is_fifo};
|
||||||
AddWaiter(waiter);
|
AddWaiter(&waiter);
|
||||||
|
|
||||||
// Perform the wait.
|
// Perform the wait.
|
||||||
return waiter.Wait(lk, timeout);
|
return waiter.Wait(lk, timeout);
|
||||||
|
@ -52,14 +49,14 @@ public:
|
||||||
|
|
||||||
// Wake up threads in order of priority.
|
// Wake up threads in order of priority.
|
||||||
for (auto it = wait_list.begin(); it != wait_list.end();) {
|
for (auto it = wait_list.begin(); it != wait_list.end();) {
|
||||||
auto& waiter = *it;
|
auto* waiter = *it;
|
||||||
if (waiter.need_count > token_count) {
|
if (waiter->need_count > token_count) {
|
||||||
it++;
|
it++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
it = wait_list.erase(it);
|
it = wait_list.erase(it);
|
||||||
token_count -= waiter.need_count;
|
token_count -= waiter->need_count;
|
||||||
waiter.cv.notify_one();
|
waiter->cv.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -70,9 +67,9 @@ public:
|
||||||
if (num_waiters) {
|
if (num_waiters) {
|
||||||
*num_waiters = wait_list.size();
|
*num_waiters = wait_list.size();
|
||||||
}
|
}
|
||||||
for (auto& waiter : wait_list) {
|
for (auto* waiter : wait_list) {
|
||||||
waiter.was_cancled = true;
|
waiter->was_cancled = true;
|
||||||
waiter.cv.notify_one();
|
waiter->cv.notify_one();
|
||||||
}
|
}
|
||||||
wait_list.clear();
|
wait_list.clear();
|
||||||
token_count = set_count < 0 ? init_count : set_count;
|
token_count = set_count < 0 ? init_count : set_count;
|
||||||
|
@ -80,7 +77,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct WaitingThread : public ListBaseHook {
|
struct WaitingThread {
|
||||||
std::condition_variable cv;
|
std::condition_variable cv;
|
||||||
u32 priority;
|
u32 priority;
|
||||||
s32 need_count;
|
s32 need_count;
|
||||||
|
@ -132,7 +129,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void AddWaiter(WaitingThread& waiter) {
|
void AddWaiter(WaitingThread* waiter) {
|
||||||
// Insert at the end of the list for FIFO order.
|
// Insert at the end of the list for FIFO order.
|
||||||
if (is_fifo) {
|
if (is_fifo) {
|
||||||
wait_list.push_back(waiter);
|
wait_list.push_back(waiter);
|
||||||
|
@ -140,16 +137,13 @@ public:
|
||||||
}
|
}
|
||||||
// Find the first with priority less then us and insert right before it.
|
// Find the first with priority less then us and insert right before it.
|
||||||
auto it = wait_list.begin();
|
auto it = wait_list.begin();
|
||||||
while (it != wait_list.end() && it->priority > waiter.priority) {
|
while (it != wait_list.end() && (*it)->priority > waiter->priority) {
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
wait_list.insert(it, waiter);
|
wait_list.insert(it, waiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
using WaitingThreads =
|
std::list<WaitingThread*> wait_list;
|
||||||
boost::intrusive::list<WaitingThread, boost::intrusive::base_hook<ListBaseHook>,
|
|
||||||
boost::intrusive::constant_time_size<false>>;
|
|
||||||
WaitingThreads wait_list;
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::atomic<s32> token_count;
|
std::atomic<s32> token_count;
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/debug.h"
|
||||||
#include "common/native_clock.h"
|
#include "common/native_clock.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/time_management.h"
|
#include "core/libraries/kernel/time_management.h"
|
||||||
|
@ -30,7 +32,8 @@ u64 PS4_SYSV_ABI sceKernelGetTscFrequency() {
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
|
u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
|
||||||
return clock->GetProcessTimeUS();
|
// TODO: this timer should support suspends, so initial ptc needs to be updated on wake up
|
||||||
|
return clock->GetTimeUS(initial_ptc);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() {
|
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() {
|
||||||
|
|
|
@ -1,496 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include "common/debug.h"
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "common/singleton.h"
|
|
||||||
#include "core/libraries/libc/libc.h"
|
|
||||||
#include "core/libraries/libc/libc_cxa.h"
|
|
||||||
#include "core/libraries/libc/libc_math.h"
|
|
||||||
#include "core/libraries/libc/libc_stdio.h"
|
|
||||||
#include "core/libraries/libc/libc_stdlib.h"
|
|
||||||
#include "core/libraries/libc/libc_string.h"
|
|
||||||
#include "core/libraries/libs.h"
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
constexpr bool log_file_libc = true; // disable it to disable logging
|
|
||||||
static u32 g_need_sceLibc = 1;
|
|
||||||
|
|
||||||
using cxa_destructor_func_t = void (*)(void*);
|
|
||||||
|
|
||||||
struct CxaDestructor {
|
|
||||||
cxa_destructor_func_t destructor_func;
|
|
||||||
void* destructor_object;
|
|
||||||
void* module_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CContext {
|
|
||||||
std::vector<CxaDestructor> cxa;
|
|
||||||
};
|
|
||||||
|
|
||||||
static PS4_SYSV_ABI int ps4___cxa_atexit(void (*func)(void*), void* arg, void* dso_handle) {
|
|
||||||
auto* cc = Common::Singleton<CContext>::Instance();
|
|
||||||
CxaDestructor c{};
|
|
||||||
c.destructor_func = func;
|
|
||||||
c.destructor_object = arg;
|
|
||||||
c.module_id = dso_handle;
|
|
||||||
cc->cxa.push_back(c);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_finalize(void* d) {
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_pure_virtual() {
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
|
|
||||||
static PS4_SYSV_ABI void ps4_init_env() {
|
|
||||||
LOG_INFO(Lib_LibC, "called");
|
|
||||||
}
|
|
||||||
|
|
||||||
static PS4_SYSV_ABI void ps4_catchReturnFromMain(int status) {
|
|
||||||
LOG_INFO(Lib_LibC, "returned = {}", status);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PS4_SYSV_ABI void ps4__Assert() {
|
|
||||||
LOG_INFO(Lib_LibC, "called");
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
|
|
||||||
PS4_SYSV_ABI void ps4__ZdlPv(void* ptr) {
|
|
||||||
std::free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
PS4_SYSV_ABI void ps4__ZSt11_Xbad_allocv() {
|
|
||||||
LOG_INFO(Lib_LibC, "called");
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
|
|
||||||
PS4_SYSV_ABI void ps4__ZSt14_Xlength_errorPKc() {
|
|
||||||
LOG_INFO(Lib_LibC, "called");
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
|
|
||||||
PS4_SYSV_ABI void* ps4__Znwm(u64 count) {
|
|
||||||
if (count == 0) {
|
|
||||||
LOG_INFO(Lib_LibC, "_Znwm count ={}", count);
|
|
||||||
BREAKPOINT();
|
|
||||||
}
|
|
||||||
void* ptr = std::malloc(count);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr u16 lowercaseTable[256] = {
|
|
||||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B,
|
|
||||||
0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
|
||||||
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
|
|
||||||
0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
|
|
||||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B,
|
|
||||||
0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
|
||||||
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073,
|
|
||||||
0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
|
|
||||||
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006A, 0x006B,
|
|
||||||
0x006C, 0x006D, 0x006E, 0x006F, 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
|
|
||||||
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083,
|
|
||||||
0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
|
|
||||||
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B,
|
|
||||||
0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
|
||||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3,
|
|
||||||
0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
|
||||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB,
|
|
||||||
0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
|
||||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3,
|
|
||||||
0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
|
||||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB,
|
|
||||||
0x00FC, 0x00FD, 0x00FE, 0x00FF,
|
|
||||||
};
|
|
||||||
|
|
||||||
const PS4_SYSV_ABI u16* ps4__Getptolower() {
|
|
||||||
return &lowercaseTable[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr u16 uppercaseTable[256] = {
|
|
||||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B,
|
|
||||||
0x000C, 0x000D, 0x000E, 0x000F, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
|
|
||||||
0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, 0x0020, 0x0021, 0x0022, 0x0023,
|
|
||||||
0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
|
|
||||||
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003A, 0x003B,
|
|
||||||
0x003C, 0x003D, 0x003E, 0x003F, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
|
||||||
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053,
|
|
||||||
0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
|
|
||||||
0x0060, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004A, 0x004B,
|
|
||||||
0x004C, 0x004D, 0x004E, 0x004F, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
|
|
||||||
0x0058, 0x0059, 0x005A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F, 0x0080, 0x0081, 0x0082, 0x0083,
|
|
||||||
0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
|
|
||||||
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009A, 0x009B,
|
|
||||||
0x009C, 0x009D, 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
|
|
||||||
0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, 0x00B0, 0x00B1, 0x00B2, 0x00B3,
|
|
||||||
0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
|
|
||||||
0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB,
|
|
||||||
0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
|
|
||||||
0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E0, 0x00E1, 0x00E2, 0x00E3,
|
|
||||||
0x00E4, 0x00E5, 0x00E6, 0x00E7, 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
|
|
||||||
0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9, 0x00FA, 0x00FB,
|
|
||||||
0x00FC, 0x00FD, 0x00FE, 0x00FF,
|
|
||||||
};
|
|
||||||
|
|
||||||
const PS4_SYSV_ABI u16* ps4__Getptoupper() {
|
|
||||||
return &uppercaseTable[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace CharacterType {
|
|
||||||
enum : u16 {
|
|
||||||
HexDigit = 0x1, // '0'-'9', 'A'-'F', 'a'-'f'
|
|
||||||
Uppercase = 0x2, // 'A'-'Z'
|
|
||||||
Space = 0x4,
|
|
||||||
Punctuation = 0x08,
|
|
||||||
Lowercase = 0x10, // 'a'-'z'
|
|
||||||
DecimalDigit = 0x20, // '0'-'9'
|
|
||||||
Control = 0x40, // CR, FF, HT, NL, VT
|
|
||||||
Control2 = 0x80, // BEL, BS, etc
|
|
||||||
ExtraSpace = 0x100,
|
|
||||||
ExtraAlphabetic = 0x200,
|
|
||||||
ExtraBlank = 0x400
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr u16 characterTypeTable[256] = {
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control | CharacterType::Control2 | CharacterType::ExtraBlank,
|
|
||||||
CharacterType::Control | CharacterType::Control2,
|
|
||||||
CharacterType::Control | CharacterType::Control2,
|
|
||||||
CharacterType::Control | CharacterType::Control2,
|
|
||||||
CharacterType::Control | CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Control2,
|
|
||||||
CharacterType::Space, //
|
|
||||||
CharacterType::Punctuation, // !
|
|
||||||
CharacterType::Punctuation, // "
|
|
||||||
CharacterType::Punctuation, // #
|
|
||||||
CharacterType::Punctuation, // $
|
|
||||||
CharacterType::Punctuation, // %
|
|
||||||
CharacterType::Punctuation, // &
|
|
||||||
CharacterType::Punctuation, // '
|
|
||||||
CharacterType::Punctuation, // (
|
|
||||||
CharacterType::Punctuation, // )
|
|
||||||
CharacterType::Punctuation, // *
|
|
||||||
CharacterType::Punctuation, // +
|
|
||||||
CharacterType::Punctuation, // ,
|
|
||||||
CharacterType::Punctuation, // -
|
|
||||||
CharacterType::Punctuation, // .
|
|
||||||
CharacterType::Punctuation, // /
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 0
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 1
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 2
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 3
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 4
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 5
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 6
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 7
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 8
|
|
||||||
CharacterType::HexDigit | CharacterType::DecimalDigit, // 9
|
|
||||||
CharacterType::Punctuation, // :
|
|
||||||
CharacterType::Punctuation, // ;
|
|
||||||
CharacterType::Punctuation, // <
|
|
||||||
CharacterType::Punctuation, // =
|
|
||||||
CharacterType::Punctuation, // >
|
|
||||||
CharacterType::Punctuation, // ?
|
|
||||||
CharacterType::Punctuation, // @
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // A
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // B
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // C
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // D
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // E
|
|
||||||
CharacterType::HexDigit | CharacterType::Uppercase, // F
|
|
||||||
CharacterType::Uppercase, // G
|
|
||||||
CharacterType::Uppercase, // H
|
|
||||||
CharacterType::Uppercase, // I
|
|
||||||
CharacterType::Uppercase, // J
|
|
||||||
CharacterType::Uppercase, // K
|
|
||||||
CharacterType::Uppercase, // L
|
|
||||||
CharacterType::Uppercase, // M
|
|
||||||
CharacterType::Uppercase, // N
|
|
||||||
CharacterType::Uppercase, // O
|
|
||||||
CharacterType::Uppercase, // P
|
|
||||||
CharacterType::Uppercase, // Q
|
|
||||||
CharacterType::Uppercase, // R
|
|
||||||
CharacterType::Uppercase, // S
|
|
||||||
CharacterType::Uppercase, // T
|
|
||||||
CharacterType::Uppercase, // U
|
|
||||||
CharacterType::Uppercase, // V
|
|
||||||
CharacterType::Uppercase, // W
|
|
||||||
CharacterType::Uppercase, // X
|
|
||||||
CharacterType::Uppercase, // Y
|
|
||||||
CharacterType::Uppercase, // Z
|
|
||||||
CharacterType::Punctuation, // [
|
|
||||||
CharacterType::Punctuation, //
|
|
||||||
CharacterType::Punctuation, // ]
|
|
||||||
CharacterType::Punctuation, // ^
|
|
||||||
CharacterType::Punctuation, // _
|
|
||||||
CharacterType::Punctuation, // `
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // a
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // b
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // c
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // d
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // e
|
|
||||||
CharacterType::HexDigit | CharacterType::Lowercase, // f
|
|
||||||
CharacterType::Lowercase, // g
|
|
||||||
CharacterType::Lowercase, // h
|
|
||||||
CharacterType::Lowercase, // i
|
|
||||||
CharacterType::Lowercase, // j
|
|
||||||
CharacterType::Lowercase, // k
|
|
||||||
CharacterType::Lowercase, // l
|
|
||||||
CharacterType::Lowercase, // m
|
|
||||||
CharacterType::Lowercase, // n
|
|
||||||
CharacterType::Lowercase, // o
|
|
||||||
CharacterType::Lowercase, // p
|
|
||||||
CharacterType::Lowercase, // q
|
|
||||||
CharacterType::Lowercase, // r
|
|
||||||
CharacterType::Lowercase, // s
|
|
||||||
CharacterType::Lowercase, // t
|
|
||||||
CharacterType::Lowercase, // u
|
|
||||||
CharacterType::Lowercase, // v
|
|
||||||
CharacterType::Lowercase, // w
|
|
||||||
CharacterType::Lowercase, // x
|
|
||||||
CharacterType::Lowercase, // y
|
|
||||||
CharacterType::Lowercase, // z
|
|
||||||
CharacterType::Punctuation, // {
|
|
||||||
CharacterType::Punctuation, // |
|
|
||||||
CharacterType::Punctuation, // }
|
|
||||||
CharacterType::Punctuation, // ~
|
|
||||||
CharacterType::Control2,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const PS4_SYSV_ABI u16* ps4__Getpctype() {
|
|
||||||
return &characterTypeTable[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
void libcSymbolsRegister(Core::Loader::SymbolsResolver* sym) {
|
|
||||||
// cxa functions
|
|
||||||
LIB_FUNCTION("3GPpjQdAMTw", "libc", 1, "libc", 1, 1, ps4___cxa_guard_acquire);
|
|
||||||
LIB_FUNCTION("9rAeANT2tyE", "libc", 1, "libc", 1, 1, ps4___cxa_guard_release);
|
|
||||||
LIB_FUNCTION("2emaaluWzUw", "libc", 1, "libc", 1, 1, ps4___cxa_guard_abort);
|
|
||||||
|
|
||||||
// stdlib functions
|
|
||||||
LIB_FUNCTION("uMei1W9uyNo", "libc", 1, "libc", 1, 1, ps4_exit);
|
|
||||||
LIB_FUNCTION("8G2LB+A3rzg", "libc", 1, "libc", 1, 1, ps4_atexit);
|
|
||||||
LIB_FUNCTION("gQX+4GDQjpM", "libc", 1, "libc", 1, 1, ps4_malloc);
|
|
||||||
LIB_FUNCTION("tIhsqj0qsFE", "libc", 1, "libc", 1, 1, ps4_free);
|
|
||||||
LIB_FUNCTION("cpCOXWMgha0", "libc", 1, "libc", 1, 1, ps4_rand);
|
|
||||||
LIB_FUNCTION("AEJdIVZTEmo", "libc", 1, "libc", 1, 1, ps4_qsort);
|
|
||||||
|
|
||||||
// math functions
|
|
||||||
LIB_FUNCTION("EH-x713A99c", "libc", 1, "libc", 1, 1, ps4_atan2f);
|
|
||||||
LIB_FUNCTION("QI-x0SL8jhw", "libc", 1, "libc", 1, 1, ps4_acosf);
|
|
||||||
LIB_FUNCTION("ZE6RNL+eLbk", "libc", 1, "libc", 1, 1, ps4_tanf);
|
|
||||||
LIB_FUNCTION("GZWjF-YIFFk", "libc", 1, "libc", 1, 1, ps4_asinf);
|
|
||||||
LIB_FUNCTION("9LCjpWyQ5Zc", "libc", 1, "libc", 1, 1, ps4_pow);
|
|
||||||
LIB_FUNCTION("cCXjU72Z0Ow", "libc", 1, "libc", 1, 1, ps4__Sin);
|
|
||||||
LIB_FUNCTION("ZtjspkJQ+vw", "libc", 1, "libc", 1, 1, ps4__Fsin);
|
|
||||||
LIB_FUNCTION("dnaeGXbjP6E", "libc", 1, "libc", 1, 1, ps4_exp2);
|
|
||||||
LIB_FUNCTION("1D0H2KNjshE", "libc", 1, "libc", 1, 1, ps4_powf);
|
|
||||||
LIB_FUNCTION("DDHG1a6+3q0", "libc", 1, "libc", 1, 1, ps4_roundf);
|
|
||||||
|
|
||||||
// string functions
|
|
||||||
LIB_FUNCTION("Ovb2dSJOAuE", "libc", 1, "libc", 1, 1, ps4_strcmp);
|
|
||||||
LIB_FUNCTION("j4ViWNHEgww", "libc", 1, "libc", 1, 1, ps4_strlen);
|
|
||||||
LIB_FUNCTION("6sJWiWSRuqk", "libc", 1, "libc", 1, 1, ps4_strncpy);
|
|
||||||
LIB_FUNCTION("+P6FRGH4LfA", "libc", 1, "libc", 1, 1, ps4_memmove);
|
|
||||||
LIB_FUNCTION("kiZSXIWd9vg", "libc", 1, "libc", 1, 1, ps4_strcpy);
|
|
||||||
LIB_FUNCTION("Ls4tzzhimqQ", "libc", 1, "libc", 1, 1, ps4_strcat);
|
|
||||||
LIB_FUNCTION("DfivPArhucg", "libc", 1, "libc", 1, 1, ps4_memcmp);
|
|
||||||
LIB_FUNCTION("Q3VBxCXhUHs", "libc", 1, "libc", 1, 1, ps4_memcpy);
|
|
||||||
LIB_FUNCTION("8zTFvBIAIN8", "libc", 1, "libc", 1, 1, ps4_memset);
|
|
||||||
LIB_FUNCTION("9yDWMxEFdJU", "libc", 1, "libc", 1, 1, ps4_strrchr);
|
|
||||||
LIB_FUNCTION("aesyjrHVWy4", "libc", 1, "libc", 1, 1, ps4_strncmp);
|
|
||||||
LIB_FUNCTION("g7zzzLDYGw0", "libc", 1, "libc", 1, 1, ps4_strdup);
|
|
||||||
|
|
||||||
// stdio functions
|
|
||||||
LIB_FUNCTION("xeYO4u7uyJ0", "libc", 1, "libc", 1, 1, ps4_fopen);
|
|
||||||
// LIB_FUNCTION("hcuQgD53UxM", "libc", 1, "libc", 1, 1, ps4_printf);
|
|
||||||
LIB_FUNCTION("Q2V+iqvjgC0", "libc", 1, "libc", 1, 1, ps4_vsnprintf);
|
|
||||||
LIB_FUNCTION("YQ0navp+YIc", "libc", 1, "libc", 1, 1, ps4_puts);
|
|
||||||
// LIB_FUNCTION("fffwELXNVFA", "libc", 1, "libc", 1, 1, ps4_fprintf);
|
|
||||||
LIB_FUNCTION("QMFyLoqNxIg", "libc", 1, "libc", 1, 1, ps4_setvbuf);
|
|
||||||
LIB_FUNCTION("uodLYyUip20", "libc", 1, "libc", 1, 1, ps4_fclose);
|
|
||||||
LIB_FUNCTION("rQFVBXp-Cxg", "libc", 1, "libc", 1, 1, ps4_fseek);
|
|
||||||
LIB_FUNCTION("SHlt7EhOtqA", "libc", 1, "libc", 1, 1, ps4_fgetpos);
|
|
||||||
LIB_FUNCTION("lbB+UlZqVG0", "libc", 1, "libc", 1, 1, ps4_fread);
|
|
||||||
LIB_FUNCTION("Qazy8LmXTvw", "libc", 1, "libc", 1, 1, ps4_ftell);
|
|
||||||
|
|
||||||
// misc
|
|
||||||
LIB_OBJ("P330P3dFF68", "libc", 1, "libc", 1, 1, &g_need_sceLibc);
|
|
||||||
LIB_OBJ("2sWzhYqFH4E", "libc", 1, "libc", 1, 1, stdout);
|
|
||||||
LIB_OBJ("H8AprKeZtNg", "libc", 1, "libc", 1, 1, stderr);
|
|
||||||
LIB_FUNCTION("bzQExy189ZI", "libc", 1, "libc", 1, 1, ps4_init_env);
|
|
||||||
LIB_FUNCTION("XKRegsFpEpk", "libc", 1, "libc", 1, 1, ps4_catchReturnFromMain);
|
|
||||||
LIB_FUNCTION("-QgqOT5u2Vk", "libc", 1, "libc", 1, 1, ps4__Assert);
|
|
||||||
LIB_FUNCTION("z+P+xCnWLBk", "libc", 1, "libc", 1, 1, ps4__ZdlPv);
|
|
||||||
LIB_FUNCTION("eT2UsmTewbU", "libc", 1, "libc", 1, 1, ps4__ZSt11_Xbad_allocv);
|
|
||||||
LIB_FUNCTION("tQIo+GIPklo", "libc", 1, "libc", 1, 1, ps4__ZSt14_Xlength_errorPKc);
|
|
||||||
LIB_FUNCTION("fJnpuVVBbKk", "libc", 1, "libc", 1, 1, ps4__Znwm);
|
|
||||||
LIB_FUNCTION("tsvEmnenz48", "libc", 1, "libc", 1, 1, ps4___cxa_atexit);
|
|
||||||
LIB_FUNCTION("H2e8t5ScQGc", "libc", 1, "libc", 1, 1, ps4___cxa_finalize);
|
|
||||||
LIB_FUNCTION("zr094EQ39Ww", "libc", 1, "libc", 1, 1, ps4___cxa_pure_virtual);
|
|
||||||
LIB_FUNCTION("1uJgoVq3bQU", "libc", 1, "libc", 1, 1, ps4__Getptolower);
|
|
||||||
LIB_FUNCTION("rcQCUr0EaRU", "libc", 1, "libc", 1, 1, ps4__Getptoupper);
|
|
||||||
LIB_FUNCTION("sUP1hBaouOw", "libc", 1, "libc", 1, 1, ps4__Getpctype);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace Libraries::LibC
|
|
|
@ -1,14 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Core::Loader {
|
|
||||||
class SymbolsResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
void libcSymbolsRegister(Core::Loader::SymbolsResolver* sym);
|
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
|
|
@ -1,161 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "core/libraries/libc/libc_cxa.h"
|
|
||||||
|
|
||||||
// adapted from
|
|
||||||
// https://opensource.apple.com/source/libcppabi/libcppabi-14/src/cxa_guard.cxx.auto.html
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
// This file implements the __cxa_guard_* functions as defined at:
|
|
||||||
// http://www.codesourcery.com/public/cxx-abi/abi.html
|
|
||||||
//
|
|
||||||
// The goal of these functions is to support thread-safe, one-time
|
|
||||||
// initialization of function scope variables. The compiler will generate
|
|
||||||
// code like the following:
|
|
||||||
//
|
|
||||||
// if ( obj_guard.first_byte == 0 ) {
|
|
||||||
// if ( __cxa_guard_acquire(&obj_guard) ) {
|
|
||||||
// try {
|
|
||||||
// ... initialize the object ...;
|
|
||||||
// }
|
|
||||||
// catch (...) {
|
|
||||||
// __cxa_guard_abort(&obj_guard);
|
|
||||||
// throw;
|
|
||||||
// }
|
|
||||||
// ... queue object destructor with __cxa_atexit() ...;
|
|
||||||
// __cxa_guard_release(&obj_guard);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Notes:
|
|
||||||
// ojb_guard is a 64-bytes in size and statically initialized to zero.
|
|
||||||
//
|
|
||||||
// Section 6.7 of the C++ Spec says "If control re-enters the declaration
|
|
||||||
// recursively while the object is being initialized, the behavior is
|
|
||||||
// undefined". This implementation calls abort().
|
|
||||||
//
|
|
||||||
|
|
||||||
// Note don't use function local statics to avoid use of cxa functions...
|
|
||||||
static pthread_mutex_t __guard_mutex;
|
|
||||||
static pthread_once_t __once_control = PTHREAD_ONCE_INIT;
|
|
||||||
|
|
||||||
static void makeRecusiveMutex() {
|
|
||||||
pthread_mutexattr_t recursiveMutexAttr;
|
|
||||||
pthread_mutexattr_init(&recursiveMutexAttr);
|
|
||||||
pthread_mutexattr_settype(&recursiveMutexAttr, PTHREAD_MUTEX_RECURSIVE);
|
|
||||||
pthread_mutex_init(&__guard_mutex, &recursiveMutexAttr);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((noinline)) static pthread_mutex_t* guard_mutex() {
|
|
||||||
pthread_once(&__once_control, &makeRecusiveMutex);
|
|
||||||
return &__guard_mutex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper functions for getting/setting flags in guard_object
|
|
||||||
static bool initializerHasRun(u64* guard_object) {
|
|
||||||
return (*((u8*)guard_object) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setInitializerHasRun(u64* guard_object) {
|
|
||||||
*((u8*)guard_object) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool inUse(u64* guard_object) {
|
|
||||||
return (((u8*)guard_object)[1] != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setInUse(u64* guard_object) {
|
|
||||||
((u8*)guard_object)[1] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setNotInUse(u64* guard_object) {
|
|
||||||
((u8*)guard_object)[1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Returns 1 if the caller needs to run the initializer and then either
|
|
||||||
// call __cxa_guard_release() or __cxa_guard_abort(). If zero is returned,
|
|
||||||
// then the initializer has already been run. This function blocks
|
|
||||||
// if another thread is currently running the initializer. This function
|
|
||||||
// aborts if called again on the same guard object without an intervening
|
|
||||||
// call to __cxa_guard_release() or __cxa_guard_abort().
|
|
||||||
//
|
|
||||||
int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object) {
|
|
||||||
// Double check that the initializer has not already been run
|
|
||||||
if (initializerHasRun(guard_object))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// We now need to acquire a lock that allows only one thread
|
|
||||||
// to run the initializer. If a different thread calls
|
|
||||||
// __cxa_guard_acquire() with the same guard object, we want
|
|
||||||
// that thread to block until this thread is done running the
|
|
||||||
// initializer and calls __cxa_guard_release(). But if the same
|
|
||||||
// thread calls __cxa_guard_acquire() with the same guard object,
|
|
||||||
// we want to abort.
|
|
||||||
// To implement this we have one global pthread recursive mutex
|
|
||||||
// shared by all guard objects, but only one at a time.
|
|
||||||
|
|
||||||
int result = ::pthread_mutex_lock(guard_mutex());
|
|
||||||
if (result != 0) {
|
|
||||||
LOG_ERROR(Lib_LibC, "pthread_mutex_lock failed with {}", result);
|
|
||||||
}
|
|
||||||
// At this point all other threads will block in __cxa_guard_acquire()
|
|
||||||
|
|
||||||
// Check if another thread has completed initializer run
|
|
||||||
if (initializerHasRun(guard_object)) {
|
|
||||||
int result = ::pthread_mutex_unlock(guard_mutex());
|
|
||||||
if (result != 0) {
|
|
||||||
LOG_ERROR(Lib_LibC, "pthread_mutex_lock failed with {}", result);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The pthread mutex is recursive to allow other lazy initialized
|
|
||||||
// function locals to be evaluated during evaluation of this one.
|
|
||||||
// But if the same thread can call __cxa_guard_acquire() on the
|
|
||||||
// *same* guard object again, we call abort();
|
|
||||||
if (inUse(guard_object)) {
|
|
||||||
LOG_ERROR(Lib_LibC,
|
|
||||||
"initializer for function local static variable called enclosing function");
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark this guard object as being in use
|
|
||||||
setInUse(guard_object);
|
|
||||||
|
|
||||||
// return non-zero to tell caller to run initializer
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Sets the first byte of the guard_object to a non-zero value.
|
|
||||||
// Releases any locks acquired by __cxa_guard_acquire().
|
|
||||||
//
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_guard_release(u64* guard_object) {
|
|
||||||
// first mark initalizer as having been run, so
|
|
||||||
// other threads won't try to re-run it.
|
|
||||||
setInitializerHasRun(guard_object);
|
|
||||||
|
|
||||||
// release global mutex
|
|
||||||
int result = ::pthread_mutex_unlock(guard_mutex());
|
|
||||||
if (result != 0) {
|
|
||||||
LOG_ERROR(Lib_LibC, "pthread_mutex_unlock failed with {}", result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Releases any locks acquired by __cxa_guard_acquire().
|
|
||||||
//
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_guard_abort(u64* guard_object) {
|
|
||||||
int result = ::pthread_mutex_unlock(guard_mutex());
|
|
||||||
if (result != 0) {
|
|
||||||
LOG_ERROR(Lib_LibC, "pthread_mutex_unlock failed with {}", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// now reset state, so possible to try to initialize again
|
|
||||||
setNotInUse(guard_object);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
|
|
@ -1,15 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
#include "common/types.h"
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI ps4___cxa_guard_acquire(u64* guard_object);
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_guard_release(u64* guard_object);
|
|
||||||
void PS4_SYSV_ABI ps4___cxa_guard_abort(u64* guard_object);
|
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
|
|
@ -1,55 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/libraries/libc/libc_math.h"
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_atan2f(float y, float x) {
|
|
||||||
return atan2f(y, x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_acosf(float num) {
|
|
||||||
return acosf(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_tanf(float num) {
|
|
||||||
return tanf(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_asinf(float num) {
|
|
||||||
return asinf(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
double PS4_SYSV_ABI ps4_pow(double base, double exponent) {
|
|
||||||
return pow(base, exponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_powf(float x, float y) {
|
|
||||||
return powf(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_roundf(float arg) {
|
|
||||||
return roundf(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
double PS4_SYSV_ABI ps4__Sin(double x) {
|
|
||||||
return sin(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4__Fsin(float arg, unsigned int m, int n) {
|
|
||||||
ASSERT(n == 0);
|
|
||||||
if (m != 0) {
|
|
||||||
return cosf(arg);
|
|
||||||
} else {
|
|
||||||
return sinf(arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double PS4_SYSV_ABI ps4_exp2(double arg) {
|
|
||||||
return exp2(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
|
|
@ -1,21 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/types.h"
|
|
||||||
|
|
||||||
namespace Libraries::LibC {
|
|
||||||
|
|
||||||
float PS4_SYSV_ABI ps4_atan2f(float y, float x);
|
|
||||||
float PS4_SYSV_ABI ps4_acosf(float num);
|
|
||||||
float PS4_SYSV_ABI ps4_tanf(float num);
|
|
||||||
float PS4_SYSV_ABI ps4_asinf(float num);
|
|
||||||
double PS4_SYSV_ABI ps4_pow(double base, double exponent);
|
|
||||||
double PS4_SYSV_ABI ps4__Sin(double x);
|
|
||||||
float PS4_SYSV_ABI ps4__Fsin(float arg, unsigned int, int);
|
|
||||||
double PS4_SYSV_ABI ps4_exp2(double arg);
|
|
||||||
float PS4_SYSV_ABI ps4_powf(float x, float y);
|
|
||||||
float PS4_SYSV_ABI ps4_roundf(float arg);
|
|
||||||
|
|
||||||
} // namespace Libraries::LibC
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue