Compare commits

..

3 Commits

Author SHA1 Message Date
IndecisiveTurtle 0dc05cfff2 vk_pipeline_cache: Remove some unnecessary checks 2024-08-20 23:58:11 +03:00
IndecisiveTurtle 3789dbe8e5 renderer_vulkan: Reduce number of compiled shaders 2024-08-19 19:52:50 +03:00
IndecisiveTurtle 68c465813c cfg: Add one more divergence case
* Seen in RDR shaders
2024-08-18 00:07:24 +03:00
271 changed files with 5090 additions and 28975 deletions

View File

@ -19,12 +19,8 @@ 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

View File

@ -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 qt6-tools-dev sudo apt-get update && sudo apt install libx11-dev libxext-dev libwayland-dev libfuse2 clang build-essential qt6-base-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

View File

@ -38,7 +38,7 @@ jobs:
host: mac host: mac
target: desktop target: desktop
arch: clang_64 arch: clang_64
archives: qtbase qttools archives: qtbase
- 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,7 +50,6 @@ 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 .

View File

@ -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-sdl.tar.gz -C upload . tar cf shadps4-macos.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-sdl name: shadps4-macos
path: shadps4-macos-sdl.tar.gz path: shadps4-macos.tar.gz

View File

@ -28,7 +28,7 @@ jobs:
host: windows host: windows
target: desktop target: desktop
arch: win64_msvc2019_64 arch: win64_msvc2019_64
archives: qtbase qttools archives: qtbase
- 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,7 +40,6 @@ 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

View File

@ -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-sdl name: shadps4-win64
path: | path: |
${{github.workspace}}/build/Release/shadPS4.exe ${{github.workspace}}/build/Release/shadPS4.exe

29
.gitmodules vendored
View File

@ -1,87 +1,66 @@
[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.git url = https://github.com/shadps4-emu/ext-ffmpeg-core
shallow = true
[submodule "externals/half"]
path = externals/half
url = https://github.com/ROCm/half.git

View File

@ -15,7 +15,6 @@ 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

View File

@ -66,24 +66,21 @@ 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.0 CONFIG) find_package(fmt 10.2.1 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 4.2.0 CONFIG) find_package(toml11 3.8.1 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.1.7 MODULE) find_package(zlib-ng 2.2.0 MODULE)
find_package(Zydis 5.0.0 CONFIG) find_package(Zydis 4.1.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)
@ -95,6 +92,10 @@ 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.
@ -109,27 +110,11 @@ add_subdirectory(externals)
include_directories(src) include_directories(src)
if(ENABLE_QT_GUI) if(ENABLE_QT_GUI)
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent LinguistTools Network) find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent)
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
@ -142,13 +127,10 @@ 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
@ -209,7 +191,6 @@ 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
@ -225,12 +206,6 @@ 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
@ -240,7 +215,21 @@ 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_internal/libc_internal.cpp set(LIBC_SOURCES src/core/libraries/libc/libc.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
) )
@ -266,7 +255,6 @@ 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
@ -280,7 +268,6 @@ 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
) )
@ -430,6 +417,7 @@ 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
@ -449,7 +437,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_propagation_pass.cpp src/shader_recompiler/ir/passes/constant_propogation_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
@ -487,7 +475,6 @@ 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
@ -521,8 +508,6 @@ 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
@ -565,10 +550,6 @@ 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
@ -596,7 +577,6 @@ 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()
@ -644,9 +624,6 @@ 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)
@ -660,45 +637,27 @@ else()
endif() endif()
if (ENABLE_QT_GUI) if (ENABLE_QT_GUI)
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network) target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent)
add_definitions(-DENABLE_QT_GUI)
endif() endif()
if (WIN32) if (WIN32)
target_link_libraries(shadps4 PRIVATE mincore winpthreads) target_link_libraries(shadps4 PRIVATE mincore winpthreads clang_rt.builtins-x86_64.lib)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
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)
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
if (MSVC) target_link_options(shadps4 PRIVATE /STACK:0x200000,0x200000)
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)

View File

@ -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 initialize member variables! // Always intitialize member variables!
int x{}; int x{};
int y{}; int y{};
}; };

View File

@ -32,30 +32,27 @@ 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>
# General information # shadPS4
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, suggest ideas or to ask for help, join our [**Discord server**](https://discord.gg/MyZRaBngxA). To discuss shadPS4 development or suggest ideas, join the [**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
> [!IMPORTANT] 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...
> 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
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. 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.
# Building # Build
## Windows ## Windows
@ -65,7 +62,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).
## Building status ## Build status
<details> <details>
<summary><b>Windows</b></summary> <summary><b>Windows</b></summary>
@ -94,16 +91,9 @@ 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>
# Debugging and reporting issues # Keyboard Mapping
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). | Controller button | Keyboard |
# 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 |
@ -160,4 +150,4 @@ Open a PR and we'll check it :)
# License # License
- [**GPL-2.0 license**](https://github.com/shadps4-emu/shadPS4/blob/main/LICENSE) - [**GPL-2.0 license**](https://github.com/shadps4-emu/shadPS4/blob/main/LICENSE)

View File

@ -1,156 +0,0 @@
<!--
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_

BIN
documents/Quickstart/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -58,24 +58,4 @@ 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 by editing the `config.toml` file found in the `user` folder created after starting the application.\ 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.
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.

View File

@ -5,96 +5,21 @@ SPDX-License-Identifier: GPL-2.0-or-later
# Build shadPS4 for Windows # Build shadPS4 for Windows
This tutorial reads as if you have none of the prerequisites already installed. If you do, just ignore the steps regarding installation. ## Download Visual Studio Community 2022
If you are building to contribute to the project, please omit `--depth 1` from the git invokations.
Note: **ARM64 is not supported!** As of writing, it will not build nor run. The instructions with respect to ARM64 are for developers only. Download link: [**Visual Studio 2022**](https://visualstudio.microsoft.com/vs/)
## Option 1: Visual Studio 2022 ## Requirements
### (Prerequisite) Download the Community edition from [**Visual Studio 2022**](https://visualstudio.microsoft.com/vs/) ### From Visual Studio Community
Once you are within the installer: - Desktop development with C++
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
### (Prerequisite) Download [**Qt**](https://doc.qt.io/qt-6/get-and-install-qt.html) ### From individual components tab install
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. - C++ Clang Compiler for Windows (17.0.3)
- MSBuild support for LLVM (Clang-cl) toolset
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. - ## Compiling
If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2019 ARM64` instead.
Go through the installation normally. If you know what you are doing, you may unselect individual components that eat up too much disk space. - Open Visual Studio Community and select the **x64-Clang-Release**, **x64-Clang-Debug** or **x64-Clang-RelWithDebInfo**. It should compile just fine.
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.

View File

@ -1,44 +1,32 @@
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
- Use unique_ptr where possible -Use unique_ptr where possible
- Replace printf/scanf with type safe fmt -Replace printf/scanf with type safe fmt
- Implemented sceKernelGetProcessTime -Implemented sceKernelGetProcessTime
- Implemented sceKernelGetProcessTimeCounter, sceKernelGetProcessTimeCounterFrequency -Implemented sceKernelGetProcessTimeCounter , sceKernelGetProcessTimeCounterFrequency
- Pause emu with P button -Pause emu with P button
- Timers rewrote with std::chrono -Timers rewrote with std::chrono
- Added sceSystemServiceGetStatus -Added sceSystemServiceGetStatus
- Initial FileSystem implementation -Initial FileSystem implementation
- 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

35
documents/readme.txt Normal file
View File

@ -0,0 +1,35 @@
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

View File

@ -25,6 +25,11 @@ 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
@ -142,17 +147,11 @@ 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) # date
# half if (APPLE AND NOT TARGET date::date-tz)
add_library(half INTERFACE) option(BUILD_TZ_LIB "" ON)
target_include_directories(half INTERFACE half/include) option(USE_SYSTEM_TZ_DB "" ON)
add_subdirectory(date)
# date
if (NOT TARGET date::date-tz)
option(BUILD_TZ_LIB "" ON)
option(USE_SYSTEM_TZ_DB "" ON)
add_subdirectory(date)
endif()
endif() endif()
# Tracy # Tracy

1
externals/discord-rpc vendored Submodule

@ -0,0 +1 @@
Subproject commit 4ec218155d73bcb8022f8f7ca72305d801f84beb

2
externals/glslang vendored

@ -1 +1 @@
Subproject commit 12cbda959b6df2af119a76a73ff906c2bed36884 Subproject commit 7c4d91e7819a1d27213aa3499953d54ae1a00e8f

1
externals/half vendored

@ -1 +0,0 @@
Subproject commit 1ddada225144cac0de8f6b5c0dd9acffd99a2e68

2
externals/robin-map vendored

@ -1 +1 @@
Subproject commit 2c48a1a50203bbaf1e3d0d64c5d726d56f8d3bb3 Subproject commit 1115dad3ffa0994e3f43b693d9b9cc99944c64c1

2
externals/sirit vendored

@ -1 +1 @@
Subproject commit 37090c74cc6e680f2bc334cac8fd182f7634a1f6 Subproject commit 8db09231c448b913ae905d5237ce2eca46e3fe87

2
externals/toml11 vendored

@ -1 +1 @@
Subproject commit 4b740127230472779c4a4d71e1a75aaa3a367a2d Subproject commit fcb1d3d7e5885edfadbbe9572991dc4b3248af58

2
externals/vma vendored

@ -1 +1 @@
Subproject commit e1bdbca9baf4d682fb6066b380f4aa4a7bdbb58a Subproject commit 871913da6a4b132b567d7b65c509600363c0041e

@ -1 +1 @@
Subproject commit d205aff40b4e15d4c568523ee6a26f85138126d9 Subproject commit 595c8d4794410a4e64b98dc58d27c0310d7ea2fd

2
externals/xbyak vendored

@ -1 +1 @@
Subproject commit ccdf68421bc8eb85693f573080fc0a5faad862db Subproject commit aabb091ae37068498751fd58202a9854408ecb0e

2
externals/xxhash vendored

@ -1 +1 @@
Subproject commit dbea33e47e7c0fe0b7c8592cd931c7430c1f130d Subproject commit ee65ff988bab34a184c700e2fbe1e1c5bc27485d

2
externals/zydis vendored

@ -1 +1 @@
Subproject commit bd73bc03b0aacaa89c9c203b9b43cd08f1b1843b Subproject commit 16c6a369c193981e9cf314126589eaa8763f92c3

View File

@ -114108,7 +114108,7 @@ STUB(
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv) _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
STUB("efPahl2FufA", STUB("efPahl2FufA",
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE) _ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlementId) STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlemetId)
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", sceAppContentAddcontEnqueueDownloadByEntitlementId) STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlemetId)
STUB( STUB(
"kJoY9lMIFzY", "kJoY9lMIFzY",
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi) _ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)

View File

@ -80897,10 +80897,10 @@ sceAppCheckerExecute
sceAppCheckerExecuteEx sceAppCheckerExecuteEx
sceAppContentAddcontDelete sceAppContentAddcontDelete
sceAppContentAddcontEnqueueDownload sceAppContentAddcontEnqueueDownload
sceAppContentAddcontEnqueueDownloadByEntitlementId sceAppContentAddcontEnqueueDownloadByEntitlemetId
sceAppContentAddcontEnqueueDownloadSp sceAppContentAddcontEnqueueDownloadSp
sceAppContentAddcontMount sceAppContentAddcontMount
sceAppContentAddcontMountByEntitlementId sceAppContentAddcontMountByEntitlemetId
sceAppContentAddcontShrink sceAppContentAddcontShrink
sceAppContentAddcontUnmount sceAppContentAddcontUnmount
sceAppContentAppParamGetInt sceAppContentAppParamGetInt

View File

@ -22,15 +22,15 @@ public:
private: private:
struct PortOut { struct PortOut {
SDL_AudioStream* stream = nullptr; bool isOpen = false;
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] = {};
u8 sample_size = 0; SDL_AudioStream* stream = nullptr;
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 ,

View File

@ -17,12 +17,10 @@ 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;
@ -48,10 +46,13 @@ 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;
} }
@ -84,14 +85,6 @@ std::string getUserName() {
return userName; return userName;
} }
bool getUseSpecialPad() {
return useSpecialPad;
}
int getSpecialPadClass() {
return specialPadClass;
}
bool debugDump() { bool debugDump() {
return isDebugDump; return isDebugDump;
} }
@ -104,10 +97,6 @@ bool nullGpu() {
return isNullGpu; return isNullGpu;
} }
bool copyGPUCmdBuffers() {
return shouldCopyGPUBuffers;
}
bool dumpShaders() { bool dumpShaders() {
return shouldDumpShaders; return shouldDumpShaders;
} }
@ -164,10 +153,6 @@ 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;
} }
@ -204,26 +189,18 @@ void setNeoMode(bool enable) {
isNeo = enable; isNeo = enable;
} }
void setLogType(const std::string& type) { void setLogType(std::string type) {
logType = type; logType = type;
} }
void setLogFilter(const std::string& type) { void setLogFilter(std::string type) {
logFilter = type; logFilter = type;
} }
void setUserName(const std::string& type) { void setUserName(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;
@ -242,10 +219,10 @@ void setIconSize(u32 size) {
void setIconSizeGrid(u32 size) { void setIconSizeGrid(u32 size) {
m_icon_size_grid = size; m_icon_size_grid = size;
} }
void setSliderPosition(u32 pos) { void setSliderPositon(u32 pos) {
m_slider_pos = pos; m_slider_pos = pos;
} }
void setSliderPositionGrid(u32 pos) { void setSliderPositonGrid(u32 pos) {
m_slider_pos_grid = pos; m_slider_pos_grid = pos;
} }
void setTableMode(u32 mode) { void setTableMode(u32 mode) {
@ -257,23 +234,19 @@ void setMainWindowWidth(u32 width) {
void setMainWindowHeight(u32 height) { void setMainWindowHeight(u32 height) {
m_window_size_H = height; m_window_size_H = height;
} }
void setPkgViewer(const std::vector<std::string>& pkgList) { void setPkgViewer(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(const std::vector<std::string>& elfList) { void setElfViewer(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(const std::vector<std::string>& recentFiles) { void setRecentFiles(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;
} }
@ -298,10 +271,10 @@ u32 getIconSize() {
u32 getIconSizeGrid() { u32 getIconSizeGrid() {
return m_icon_size_grid; return m_icon_size_grid;
} }
u32 getSliderPosition() { u32 getSliderPositon() {
return m_slider_pos; return m_slider_pos;
} }
u32 getSliderPositionGrid() { u32 getSliderPositonGrid() {
return m_slider_pos_grid; return m_slider_pos_grid;
} }
u32 getTableMode() { u32 getTableMode() {
@ -323,10 +296,6 @@ 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;
} }
@ -357,20 +326,12 @@ 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);
@ -393,6 +354,12 @@ 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");
@ -412,7 +379,6 @@ 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")) {
@ -446,12 +412,9 @@ 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;
@ -462,6 +425,7 @@ 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;
@ -478,7 +442,6 @@ 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;
@ -495,8 +458,6 @@ 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;
@ -505,7 +466,6 @@ 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;
} }

View File

@ -17,17 +17,14 @@ 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();
@ -37,7 +34,6 @@ 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);
@ -47,13 +43,10 @@ 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(const std::string& type); void setUserName(std::string type);
void setUseSpecialPad(bool use); void setLogType(std::string type);
void setSpecialPadClass(int type); void setLogFilter(std::string 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);
@ -69,15 +62,14 @@ 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 setSliderPosition(u32 pos); void setSliderPositon(u32 pos);
void setSliderPositionGrid(u32 pos); void setSliderPositonGrid(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(const std::vector<std::string>& pkgList); void setPkgViewer(std::vector<std::string> pkgList);
void setElfViewer(const std::vector<std::string>& elfList); void setElfViewer(std::vector<std::string> elfList);
void setRecentFiles(const std::vector<std::string>& recentFiles); void setRecentFiles(std::vector<std::string> recentFiles);
void setEmulatorLanguage(std::string language);
u32 getMainWindowGeometryX(); u32 getMainWindowGeometryX();
u32 getMainWindowGeometryY(); u32 getMainWindowGeometryY();
@ -87,15 +79,14 @@ std::string getGameInstallDir();
u32 getMainWindowTheme(); u32 getMainWindowTheme();
u32 getIconSize(); u32 getIconSize();
u32 getIconSizeGrid(); u32 getIconSizeGrid();
u32 getSliderPosition(); u32 getSliderPositon();
u32 getSliderPositionGrid(); u32 getSliderPositonGrid();
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();

View File

@ -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 MarkersPalette : int { enum MarkersPallete : int {
EmulatorMarkerColor = 0x264653, EmulatorMarkerColor = 0x264653,
RendererMarkerColor = 0x2a9d8f, RendererMarkerColor = 0x2a9d8f,
HleMarkerColor = 0xe9c46a, HleMarkerColor = 0xe9c46a,

View File

@ -217,7 +217,7 @@ void IOFile::Close() {
file = nullptr; file = nullptr;
#ifdef _WIN64 #ifdef _WIN64
if (file_mapping && file_access_mode == FileAccessMode::ReadWrite) { if (file_mapping) {
CloseHandle(std::bit_cast<HANDLE>(file_mapping)); CloseHandle(std::bit_cast<HANDLE>(file_mapping));
} }
#endif #endif
@ -259,7 +259,8 @@ 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 = hfile; mapping = CreateFileMapping2(hfile, NULL, FILE_MAP_READ, PAGE_READONLY, SEC_COMMIT, 0, NULL,
NULL, 0);
} }
file_mapping = std::bit_cast<uintptr_t>(mapping); file_mapping = std::bit_cast<uintptr_t>(mapping);

View File

@ -112,7 +112,6 @@ 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) \

View File

@ -79,7 +79,6 @@ 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

View File

@ -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(u64 base_ptc /*= 0*/) const { u64 NativeClock::GetTimeNS() const {
return MultiplyHigh(GetUptime() - base_ptc, ns_rdtsc_factor); return MultiplyHigh(GetUptime(), ns_rdtsc_factor);
} }
u64 NativeClock::GetTimeUS(u64 base_ptc /*= 0*/) const { u64 NativeClock::GetTimeUS() const {
return MultiplyHigh(GetUptime() - base_ptc, us_rdtsc_factor); return MultiplyHigh(GetUptime(), us_rdtsc_factor);
} }
u64 NativeClock::GetTimeMS(u64 base_ptc /*= 0*/) const { u64 NativeClock::GetTimeMS() const {
return MultiplyHigh(GetUptime() - base_ptc, ms_rdtsc_factor); return MultiplyHigh(GetUptime(), ms_rdtsc_factor);
} }
u64 NativeClock::GetUptime() const { u64 NativeClock::GetUptime() const {

View File

@ -16,9 +16,9 @@ public:
return rdtsc_frequency; return rdtsc_frequency;
} }
u64 GetTimeNS(u64 base_ptc = 0) const; u64 GetTimeNS() const;
u64 GetTimeUS(u64 base_ptc = 0) const; u64 GetTimeUS() const;
u64 GetTimeMS(u64 base_ptc = 0) const; u64 GetTimeMS() const;
u64 GetUptime() const; u64 GetUptime() const;
u64 GetProcessTimeUS() const; u64 GetProcessTimeUS() const;

View File

@ -8,7 +8,6 @@
#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
@ -27,52 +26,23 @@ 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 =
CFURLRef untranslocated_url_ref = UntranslocateBundlePath(bundle_url_ref); CFURLCopyFileSystemPath(bundle_url_ref, kCFURLPOSIXPathStyle)) {
SCOPE_EXIT { SCOPE_EXIT {
if (untranslocated_url_ref) { CFRelease(bundle_path_ref);
CFRelease(untranslocated_url_ref); };
char app_bundle_path[MAXPATHLEN];
if (CFStringGetFileSystemRepresentation(bundle_path_ref, app_bundle_path,
sizeof(app_bundle_path))) {
std::filesystem::path bundle_path{app_bundle_path};
return bundle_path.parent_path();
} }
};
char app_bundle_path[MAXPATHLEN];
if (CFURLGetFileSystemRepresentation(
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};
return bundle_path.parent_path();
} }
} }
} }
@ -104,9 +74,6 @@ 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;
}(); }();

View File

@ -20,9 +20,6 @@ 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";
@ -38,9 +35,6 @@ 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";

View File

@ -28,13 +28,9 @@ struct SlotId {
template <class T> template <class T>
class SlotVector { class SlotVector {
constexpr static std::size_t InitialCapacity = 2048; constexpr static std::size_t InitialCapacity = 1024;
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) {
@ -71,6 +67,19 @@ 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);
@ -142,8 +151,7 @@ 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));
const std::size_t new_free_size = free_list.size(); std::iota(free_list.begin() + old_free_size, free_list.end(),
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;

View File

@ -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(const u128& dividend, u32 divisor) { [[nodiscard]] static inline std::pair<u64, u64> Divide128On32(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)

View File

@ -2,7 +2,6 @@
// 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"
@ -99,7 +98,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_MSG(backing_handle, "{}", Common::GetLastErrorMsg()); ASSERT(backing_handle);
// 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,
@ -107,7 +106,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_MSG(ret == backing_base, "{}", Common::GetLastErrorMsg()); ASSERT(ret == backing_base);
} }
~Impl() { ~Impl() {
@ -130,10 +129,9 @@ 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 + aligned_size <= it->upper(), ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + 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.
@ -142,7 +140,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 + aligned_size; const VAddr virtual_end = virtual_addr + 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) {
@ -163,23 +161,11 @@ 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;
if (fd && prot == PAGE_READONLY) { ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr), phys_addr,
DWORD resultvar; size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
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), aligned_size, VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), 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());
@ -469,12 +455,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, bool readonly_file) { PAddr phys_base, bool is_exec, bool has_backing) {
#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 && !readonly_file); impl->Unmap(virtual_addr, size, has_backing);
// 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),

View File

@ -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, bool readonly_file); PAddr phys_base, bool is_exec, bool has_backing);
void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms); void Protect(VAddr virtual_addr, size_t size, MemoryPermission perms);

View File

@ -114108,7 +114108,7 @@ STUB(
_ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv) _ZN3sce2Np9CppWebApi6Common12IntrusivePtrINS1_7Matches2V124RequestCompetitiveResultEE7add_refEv)
STUB("efPahl2FufA", STUB("efPahl2FufA",
_ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE) _ZN3sce2Np9CppWebApi30CommunicationRestrictionStatus2V35Error8fromJsonERKNS_4Json5ValueE)
STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlementId) STUB("efX3lrPwdKA", sceAppContentAddcontMountByEntitlemetId)
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", sceAppContentAddcontEnqueueDownloadByEntitlementId) STUB("kJmjt81mXKQ", sceAppContentAddcontEnqueueDownloadByEntitlemetId)
STUB( STUB(
"kJoY9lMIFzY", "kJoY9lMIFzY",
_ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi) _ZN3sce2Np9CppWebApi6Common8IteratorINS2_12IntrusivePtrINS1_21AdvancedPlayerProfile2V138MatchCompletionRateDisconnectedMetricsEEEEmmEi)

View File

@ -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 implementation without function name details // a default implemetnation 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

View File

@ -15,7 +15,6 @@
#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
@ -31,12 +30,6 @@ 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));
} }
@ -73,12 +66,6 @@ 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: {
@ -123,135 +110,51 @@ static Xbyak::Reg AllocateScratchRegister(
#ifdef __APPLE__ #ifdef __APPLE__
static pthread_key_t stack_pointer_slot; static constexpr u32 MaxSavedRegisters = 3;
static pthread_key_t patch_stack_slot; static pthread_key_t register_save_slots[MaxSavedRegisters];
static std::once_flag patch_context_slots_init_flag; static std::once_flag register_save_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 InitializePatchContextSlots() { static void InitializeRegisterSaveSlots() {
ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0, for (u32 i = 0; i < MaxSavedRegisters; i++) {
"Unable to allocate thread-local register for stack pointer."); ASSERT_MSG(pthread_key_create(&register_save_slots[i], nullptr) == 0,
ASSERT_MSG(pthread_key_create(&patch_stack_slot, nullptr) == 0, "Unable to allocate thread-local register save slot {}", i);
"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);
} }
} }
/// Saves the stack pointer to thread local storage and loads the patch stack.
static void SaveStack(Xbyak::CodeGenerator& c) {
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
// Save stack pointer and load patch stack.
c.putSeg(gs);
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) { static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
SaveStack(c); ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to save {} registers.",
regs.size());
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
u32 index = 0;
for (const auto& reg : regs) { for (const auto& reg : regs) {
c.push(reg.cvt64()); const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
c.putSeg(gs);
c.mov(qword[offset], 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) {
SaveStack(c); ASSERT_MSG(regs.size() <= MaxSavedRegisters, "Not enough space to restore {} registers.",
regs.size());
std::call_once(register_save_init_flag, &InitializeRegisterSaveSlots);
u32 index = 0;
for (const auto& reg : regs) { for (const auto& reg : regs) {
c.pop(reg.cvt64()); const auto offset = reinterpret_cast<void*>(register_save_slots[index++] * sizeof(void*));
}
RestoreStack(c);
}
/// Switches to the patch stack and stores all registers. c.putSeg(gs);
static void SaveContext(Xbyak::CodeGenerator& c) { c.mov(reg.cvt64(), qword[offset]);
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]);
@ -301,9 +204,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, {scratch2, scratch1}); RestoreRegisters(c, {scratch1, scratch2});
} else { } else {
RestoreRegisters(c, {shift, scratch2, scratch1}); RestoreRegisters(c, {scratch1, scratch2, shift});
} }
} }
@ -355,138 +258,10 @@ static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerat
RestoreRegisters(c, {scratch}); RestoreRegisters(c, {scratch});
} }
static __attribute__((sysv_abi)) void PerformVCVTPH2PS(float* out, const half_float::half* in, bool FilterRosetta2Only(const ZydisDecodedOperand*) {
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, nullptr, 0) != 0) { if (sysctlbyname("sysctl.proc_translated", &ret, &size, NULL, 0) != 0) {
return false; return false;
} }
return ret; return ret;
@ -564,16 +339,12 @@ static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
// Patches for instruction sets not supported by Rosetta 2. // BMI1 instructions that are not supported by Rosetta 2 on Apple Silicon.
// 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
}; };

View File

@ -9,12 +9,6 @@ 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);

View File

@ -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(PkgDerivedKey3Keyset::Prime1, 0x80)); params.SetPrime1(CryptoPP::Integer(pkg_derived_key3_keyset.Prime1, 0x80));
params.SetPrime2(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime2, 0x80)); params.SetPrime2(CryptoPP::Integer(pkg_derived_key3_keyset.Prime2, 0x80));
params.SetPublicExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PublicExponent, 4)); params.SetPublicExponent(CryptoPP::Integer(pkg_derived_key3_keyset.PublicExponent, 4));
params.SetPrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PrivateExponent, 0x100)); params.SetPrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.PrivateExponent, 0x100));
params.SetModPrime1PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent1, 0x80)); params.SetModPrime1PrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.Exponent1, 0x80));
params.SetModPrime2PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent2, 0x80)); params.SetModPrime2PrivateExponent(CryptoPP::Integer(pkg_derived_key3_keyset.Exponent2, 0x80));
params.SetModulus(CryptoPP::Integer(PkgDerivedKey3Keyset::Modulus, 0x100)); params.SetModulus(CryptoPP::Integer(pkg_derived_key3_keyset.Modulus, 0x100));
params.SetMultiplicativeInverseOfPrime2ModPrime1( params.SetMultiplicativeInverseOfPrime2ModPrime1(
CryptoPP::Integer(PkgDerivedKey3Keyset::Coefficient, 0x80)); CryptoPP::Integer(pkg_derived_key3_keyset.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::Prime1, 0x80)); params.SetPrime1(CryptoPP::Integer(FakeKeyset_keyset.Prime1, 0x80));
params.SetPrime2(CryptoPP::Integer(FakeKeyset::Prime2, 0x80)); params.SetPrime2(CryptoPP::Integer(FakeKeyset_keyset.Prime2, 0x80));
params.SetPublicExponent(CryptoPP::Integer(FakeKeyset::PublicExponent, 4)); params.SetPublicExponent(CryptoPP::Integer(FakeKeyset_keyset.PublicExponent, 4));
params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset::PrivateExponent, 0x100)); params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.PrivateExponent, 0x100));
params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent1, 0x80)); params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.Exponent1, 0x80));
params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent2, 0x80)); params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset_keyset.Exponent2, 0x80));
params.SetModulus(CryptoPP::Integer(FakeKeyset::Modulus, 0x100)); params.SetModulus(CryptoPP::Integer(FakeKeyset_keyset.Modulus, 0x100));
params.SetMultiplicativeInverseOfPrime2ModPrime1( params.SetMultiplicativeInverseOfPrime2ModPrime1(
CryptoPP::Integer(FakeKeyset::Coefficient, 0x80)); CryptoPP::Integer(FakeKeyset_keyset.Coefficient, 0x80));
CryptoPP::RSA::PrivateKey privateKey(params); CryptoPP::RSA::PrivateKey privateKey(params);
@ -46,22 +46,25 @@ 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(CryptoPP::Integer(DebugRifKeyset::Prime1, sizeof(DebugRifKeyset::Prime1))); params.SetPrime1(
params.SetPrime2(CryptoPP::Integer(DebugRifKeyset::Prime2, sizeof(DebugRifKeyset::Prime2))); CryptoPP::Integer(DebugRifKeyset_keyset.Prime1, sizeof(DebugRifKeyset_keyset.Prime1)));
params.SetPrime2(
CryptoPP::Integer(DebugRifKeyset_keyset.Prime2, sizeof(DebugRifKeyset_keyset.Prime2)));
params.SetPublicExponent( params.SetPublicExponent(CryptoPP::Integer(DebugRifKeyset_keyset.PrivateExponent,
CryptoPP::Integer(DebugRifKeyset::PublicExponent, sizeof(DebugRifKeyset::PublicExponent))); sizeof(DebugRifKeyset_keyset.PrivateExponent)));
params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset::PrivateExponent, params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.PrivateExponent,
sizeof(DebugRifKeyset::PrivateExponent))); sizeof(DebugRifKeyset_keyset.PrivateExponent)));
params.SetModPrime1PrivateExponent( params.SetModPrime1PrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.Exponent1,
CryptoPP::Integer(DebugRifKeyset::Exponent1, sizeof(DebugRifKeyset::Exponent1))); sizeof(DebugRifKeyset_keyset.Exponent1)));
params.SetModPrime2PrivateExponent( params.SetModPrime2PrivateExponent(CryptoPP::Integer(DebugRifKeyset_keyset.Exponent2,
CryptoPP::Integer(DebugRifKeyset::Exponent2, sizeof(DebugRifKeyset::Exponent2))); sizeof(DebugRifKeyset_keyset.Exponent2)));
params.SetModulus(CryptoPP::Integer(DebugRifKeyset::Modulus, sizeof(DebugRifKeyset::Modulus))); params.SetModulus(
params.SetMultiplicativeInverseOfPrime2ModPrime1( CryptoPP::Integer(DebugRifKeyset_keyset.Modulus, sizeof(DebugRifKeyset_keyset.Modulus)));
CryptoPP::Integer(DebugRifKeyset::Coefficient, sizeof(DebugRifKeyset::Coefficient))); params.SetMultiplicativeInverseOfPrime2ModPrime1(CryptoPP::Integer(
DebugRifKeyset_keyset.Coefficient, sizeof(DebugRifKeyset_keyset.Coefficient)));
CryptoPP::RSA::PrivateKey privateKey(params); CryptoPP::RSA::PrivateKey privateKey(params);

View File

@ -17,6 +17,10 @@
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();

View File

@ -7,299 +7,384 @@
class FakeKeyset { class FakeKeyset {
public: public:
// Constructor // Constructor
static constexpr CryptoPP::byte Exponent1[] = { const 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)
static constexpr CryptoPP::byte Exponent2[] = { const 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
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1}; const CryptoPP::byte* PublicExponent;
// (InverseQ)(q) = 1 mod p // (InverseQ)(q) = 1 mod p
static constexpr CryptoPP::byte Coefficient[] = { const 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
static constexpr CryptoPP::byte Modulus[] = { const 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
static constexpr CryptoPP::byte Prime1[] = { const 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
static constexpr CryptoPP::byte Prime2[] = { const CryptoPP::byte* Prime2;
0xC7, 0x9E, 0x47, 0x58, 0x00, 0x7D, 0x62, 0x82, 0xB0, 0xD2, 0x22, 0x81, 0xD4, 0xA8, 0x97, const CryptoPP::byte* PrivateExponent;
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, // Constructor
0x70, 0xE8, 0x76, 0x58, 0xC8, 0xB2, 0x91, 0xCE, 0x9C, 0xC3, 0xE9, 0x09, 0x7F, 0x2E, 0x47, FakeKeyset() {
0x97, 0xCC, 0x90, 0x39, 0x15, 0x35, 0x31, 0xDE, 0x1F, 0x0C, 0x8C, 0x0D, 0xC1, 0xC2, 0x92, // Initialize PrivateExponent
0xBE, 0x97, 0xBF, 0x2F, 0x91, 0xA1, 0x8C, 0x7D, 0x50, 0xA8, 0x21, 0x2F, 0xD7, 0xA2, 0x9A, PrivateExponent = new CryptoPP::byte[0x100]{
0x7E, 0xB5, 0xA7, 0x2A, 0x90, 0x02, 0xD9, 0xF3, 0x3D, 0xD1, 0xEB, 0xB8, 0xE0, 0x5A, 0x79, 0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D,
0x9E, 0x7D, 0x8D, 0xCA, 0x18, 0x6D, 0xBD, 0x9E, 0xA1, 0x80, 0x28, 0x6B, 0x2A, 0xFE, 0x51, 0xFA, 0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD,
0x24, 0x9B, 0x6F, 0x4D, 0x84, 0x77, 0x80, 0x23}; 0xDB, 0xFD, 0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2,
static constexpr CryptoPP::byte PrivateExponent[] = { 0xB1, 0x22, 0x5C, 0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66,
0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D, 0xFA, 0xD1, 0x49, 0x2C, 0x8F, 0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E,
0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD, 0xDB, 0xFD, 0xD2, 0x21, 0x28, 0x83, 0x09, 0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63,
0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2, 0xB1, 0x22, 0x5C, 0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14, 0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8,
0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66, 0xD1, 0x49, 0x2C, 0x8F, 0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77, 0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26,
0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E, 0xD2, 0x21, 0x28, 0x83, 0x09, 0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90, 0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44,
0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63, 0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14, 0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22, 0x58, 0xD5, 0x43, 0x82, 0x49,
0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8, 0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77, 0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0, 0xCE, 0x3D, 0xDF, 0xF4,
0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26, 0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90, 0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93, 0x23, 0xDB, 0xBA,
0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44, 0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22, 0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5, 0x71, 0x67,
0x58, 0xD5, 0x43, 0x82, 0x49, 0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0, 0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5, 0x6C,
0xCE, 0x3D, 0xDF, 0xF4, 0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93, 0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1,
0x23, 0xDB, 0xBA, 0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5, 0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68,
0x71, 0x67, 0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5, 0x85, 0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A,
0x6C, 0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1, 0xEC, 0x39, 0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A,
0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68, 0x85, 0x79, 0x89, 0xC6, 0xB1};
0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A, 0xEC, 0x39,
0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A, 0x79, 0x89, 0xC6, // Initialize Exponent1
0xB1}; Exponent1 = new CryptoPP::byte[0x80]{
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;
static constexpr CryptoPP::byte Exponent1[] = { const 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)
static constexpr CryptoPP::byte Exponent2[] = { const 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
static constexpr CryptoPP::byte PublicExponent[] = {0x00, 0x01, 0x00, 0x01}; const CryptoPP::byte* PublicExponent;
// (InverseQ)(q) = 1 mod p // (InverseQ)(q) = 1 mod p
static constexpr CryptoPP::byte Coefficient[] = { const 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
static constexpr CryptoPP::byte Modulus[] = { const 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
static constexpr CryptoPP::byte Prime1[] = { const 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
static constexpr CryptoPP::byte Prime2[] = { const CryptoPP::byte* Prime2;
0xD9, 0x6C, 0xC2, 0x0C, 0xF7, 0xAE, 0xD1, 0xF3, 0x3B, 0x3B, 0x49, 0x1E, 0x9F, 0x12, 0x9C, const CryptoPP::byte* PrivateExponent;
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, // Constructor
0xDB, 0xD4, 0x25, 0x3E, 0x26, 0xED, 0xEA, 0xB8, 0xF7, 0x49, 0xFE, 0xA2, 0x94, 0xE6, 0xF2, DebugRifKeyset() {
0x08, 0x92, 0xA7, 0x85, 0xF5, 0x30, 0xB9, 0x84, 0x22, 0xBF, 0xCA, 0xF0, 0x5F, 0xCB, 0x31, // Initialize PrivateExponent
0x20, 0x34, 0x49, 0x16, 0x76, 0x34, 0xCC, 0x7A, 0xCB, 0x96, 0xFE, 0x78, 0x7A, 0x41, 0xFE, PrivateExponent = new CryptoPP::byte[0x100]{
0x9A, 0xA2, 0x23, 0xF7, 0x68, 0x80, 0xD6, 0xCE, 0x4A, 0x78, 0xA5, 0xB7, 0x05, 0x77, 0x81, 0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83,
0x1F, 0xDE, 0x5E, 0xA8, 0x6E, 0x3E, 0x87, 0xEC, 0x44, 0xD2, 0x69, 0xC6, 0x54, 0x91, 0x6B, 0x01, 0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97,
0x5E, 0x13, 0x8A, 0x03, 0x87, 0x05, 0x31, 0x8D}; 0x64, 0xEC, 0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0,
static constexpr CryptoPP::byte PrivateExponent[] = { 0xC6, 0xA3, 0x73, 0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8,
0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83, 0x01, 0x23, 0xD8, 0x1B, 0x61, 0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8,
0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97, 0x64, 0xEC, 0x03, 0x4A, 0xBF, 0xFE, 0xF9, 0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F,
0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0, 0xC6, 0xA3, 0x73, 0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28, 0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF,
0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8, 0x23, 0xD8, 0x1B, 0x61, 0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36, 0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC,
0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8, 0x03, 0x4A, 0xBF, 0xFE, 0xF9, 0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E, 0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC,
0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F, 0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28, 0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14, 0x3D, 0x90, 0xE4, 0xDE, 0x5D,
0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF, 0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36, 0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97, 0x2D, 0x89, 0x2A, 0x51,
0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC, 0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E, 0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F, 0xA1, 0x8A, 0x69,
0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC, 0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14, 0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C, 0xC7, 0xE8,
0x3D, 0x90, 0xE4, 0xDE, 0x5D, 0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97, 0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61, 0xB9,
0x2D, 0x89, 0x2A, 0x51, 0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F, 0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49,
0xA1, 0x8A, 0x69, 0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C, 0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC,
0xC7, 0xE8, 0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61, 0xB3, 0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4,
0xB9, 0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49, 0xAF, 0x6E, 0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3,
0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC, 0xB3, 0xF1, 0xCF, 0x14, 0xA5};
0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4, 0xAF, 0x6E,
0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3, 0xF1, 0xCF, 0x14, // Initialize Exponent1
0xA5}; Exponent1 = new CryptoPP::byte[0x80]{
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;
static constexpr CryptoPP::byte Exponent1[] = { const 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)
static constexpr CryptoPP::byte Exponent2[] = { const 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
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1}; const CryptoPP::byte* PublicExponent;
// (InverseQ)(q) = 1 mod p // (InverseQ)(q) = 1 mod p
static constexpr CryptoPP::byte Coefficient[] = { const 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
static constexpr CryptoPP::byte Modulus[] = { const 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
static constexpr CryptoPP::byte Prime1[] = { const 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
static constexpr CryptoPP::byte Prime2[] = { const CryptoPP::byte* Prime2;
0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0, 0xD9, 0x40, const CryptoPP::byte* PrivateExponent;
0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65, 0xF9, 0xC3, 0x61, 0x0F,
0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40, 0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89, PkgDerivedKey3Keyset() {
0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F, 0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9,
0xB4, 0xC7, 0xB5, 0x1B, 0x05, 0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E, Prime1 = new CryptoPP::byte[0x80]{
0x5C, 0xFB, 0x92, 0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C, 0xF9, 0x67, 0xAD, 0x99, 0x12, 0x31, 0x0C, 0x56, 0xA2, 0x2E, 0x16, 0x1C, 0x46,
0x07, 0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5, 0x53, 0xB3, 0x4D, 0x5B, 0x43, 0xBE, 0x42, 0xA2, 0xF6, 0x86, 0x96, 0x80, 0x42, 0xC3,
0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92, 0x01, 0xEE, 0x10, 0xC7, 0x3F, 0xC3, 0x42, 0xF5, 0x87, 0x49, 0x33, 0x9F, 0x07, 0x5D, 0x6E, 0x2C,
0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73}; 0x04, 0xFD, 0xE3, 0xE1, 0xB2, 0xAE, 0x0A, 0x0C, 0xF0, 0xC7, 0xA6, 0x1C, 0xA1,
static constexpr CryptoPP::byte PrivateExponent[] = { 0x63, 0x50, 0xC8, 0x09, 0x9C, 0x51, 0x24, 0x52, 0x6C, 0x5E, 0x5E, 0xBD, 0x1E,
0x32, 0xD9, 0x03, 0x90, 0x8F, 0xBD, 0xB0, 0x8F, 0x57, 0x2B, 0x28, 0x5E, 0x0B, 0x8D, 0xB3, 0x27, 0x06, 0xBB, 0xBC, 0x9E, 0x94, 0xE1, 0x35, 0xD4, 0x6D, 0xB3, 0xCB, 0x3C,
0xEA, 0x5C, 0xD1, 0x7E, 0xA8, 0x90, 0x88, 0x8C, 0xDD, 0x6A, 0x80, 0xBB, 0xB1, 0xDF, 0xC1, 0x68, 0xDD, 0x68, 0xB3, 0xFE, 0x6C, 0xCB, 0x8D, 0x82, 0x20, 0x76, 0x23, 0x63,
0xF7, 0x0D, 0xAA, 0x32, 0xF0, 0xB7, 0x7C, 0xCB, 0x88, 0x80, 0x0E, 0x8B, 0x64, 0xB0, 0xBE, 0xB7, 0xE9, 0x68, 0x10, 0x01, 0x4E, 0xDC, 0xBA, 0x27, 0x5D, 0x01, 0xC1, 0x2D,
0x4C, 0xD6, 0x0E, 0x9B, 0x8C, 0x1E, 0x2A, 0x64, 0xE1, 0xF3, 0x5C, 0xD7, 0x76, 0x01, 0x41, 0x80, 0x5E, 0x2B, 0xAF, 0x82, 0x6B, 0xD8, 0x84, 0xB6, 0x10, 0x52, 0x86, 0xA7,
0x5E, 0x93, 0x5C, 0x94, 0xFE, 0xDD, 0x46, 0x62, 0xC3, 0x1B, 0x5A, 0xE2, 0xA0, 0xBC, 0x2D, 0x89, 0x8E, 0xAE, 0x9A, 0xE2, 0x89, 0xC6, 0xF7, 0xD5, 0x87, 0xFB};
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, Prime2 = new CryptoPP::byte[0x80]{
0xAB, 0x16, 0x62, 0x04, 0x19, 0xBA, 0xFB, 0x90, 0xFF, 0xE2, 0x30, 0x50, 0x89, 0x6E, 0xCB, 0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0,
0x56, 0xB2, 0xEB, 0xC0, 0x91, 0x16, 0x92, 0x5E, 0x30, 0x8E, 0xAE, 0xC7, 0x94, 0x5D, 0xFD, 0xD9, 0x40, 0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65,
0x35, 0xE1, 0x20, 0xF8, 0xAD, 0x3E, 0xBC, 0x08, 0xBF, 0xC0, 0x36, 0x74, 0x9F, 0xD5, 0xBB, 0xF9, 0xC3, 0x61, 0x0F, 0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40,
0x52, 0x08, 0xFD, 0x06, 0x66, 0xF3, 0x7A, 0xB3, 0x04, 0xF4, 0x75, 0x29, 0x5D, 0xE9, 0x5F, 0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89, 0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F,
0xAA, 0x10, 0x30, 0xB2, 0x0F, 0x5A, 0x1A, 0xC1, 0x2A, 0xB3, 0xFE, 0xCB, 0x21, 0xAD, 0x80, 0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9, 0xB4, 0xC7, 0xB5, 0x1B, 0x05,
0xEC, 0x8F, 0x20, 0x09, 0x1C, 0xDB, 0xC5, 0x58, 0x94, 0xC2, 0x9C, 0xC6, 0xCE, 0x82, 0x65, 0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E, 0x5C, 0xFB, 0x92,
0x3E, 0x57, 0x90, 0xBC, 0xA9, 0x8B, 0x06, 0xB4, 0xF0, 0x72, 0xF6, 0x77, 0xDF, 0x98, 0x64, 0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C, 0x07,
0xF1, 0xEC, 0xFE, 0x37, 0x2D, 0xBC, 0xAE, 0x8C, 0x08, 0x81, 0x1F, 0xC3, 0xC9, 0x89, 0x1A, 0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5,
0xC7, 0x42, 0x82, 0x4B, 0x2E, 0xDC, 0x8E, 0x8D, 0x73, 0xCE, 0xB1, 0xCC, 0x01, 0xD9, 0x08, 0x53, 0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92,
0x70, 0x87, 0x3C, 0x44, 0x08, 0xEC, 0x49, 0x8F, 0x81, 0x5A, 0xE2, 0x40, 0xFF, 0x77, 0xFC, 0x01, 0xEE, 0x10, 0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73};
0x0D}; PrivateExponent = new CryptoPP::byte[0x100]{
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};
};
}; };

View File

@ -67,19 +67,15 @@ 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;
file.Read(entry.id); std::memcpy(&entry, &pkg[offset + i * 0x20], sizeof(entry));
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);
@ -117,6 +113,9 @@ 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;
@ -127,18 +126,9 @@ 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;
file.Read(entry.id); std::memcpy(&entry, &pkg[offset + i * 0x20], sizeof(entry));
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);
@ -149,15 +139,8 @@ 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);
file.Seek(entry.offset); out.WriteRaw<u8>(pkg.data() + entry.offset, entry.size);
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;
} }
@ -195,25 +178,14 @@ 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);
file.Seek(entry.offset); out.WriteRaw<u8>(pkg.data() + entry.offset, entry.size);
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);
file.Seek(entry.offset); std::span<u8> cipherNp(pkg.data() + entry.offset, entry.size);
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_));
@ -225,8 +197,6 @@ 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
@ -244,31 +214,28 @@ 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; // Read encrypted pfs_image
std::vector<u8> pfs_encrypted(length);
file.Seek(pkgheader.pfs_image_offset);
file.Read(pfs_encrypted);
file.Close();
// Decrypt the pfs_image.
std::vector<u8> pfs_decrypted(length);
PKG::crypto.decryptPFS(dataKey, tweakKey, pfs_encrypted, pfs_decrypted, 0);
// Retrieve PFSC from decrypted pfs_image.
pfsc_offset = GetPFSCOffset(pfs_decrypted);
std::vector<u8> pfsc(length); std::vector<u8> pfsc(length);
if (length != 0) { std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
// Read encrypted pfs_image
std::vector<u8> pfs_encrypted(length);
file.Seek(pkgheader.pfs_image_offset);
file.Read(pfs_encrypted);
file.Close();
// Decrypt the pfs_image.
std::vector<u8> pfs_decrypted(length);
PKG::crypto.decryptPFS(dataKey, tweakKey, pfs_encrypted, pfs_decrypted, 0);
// Retrieve PFSC from decrypted pfs_image. PFSCHdr pfsChdr;
pfsc_offset = GetPFSCOffset(pfs_decrypted); std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr));
std::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
PFSCHdr pfsChdr; const int num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2);
std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr)); sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset.
num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2); for (int i = 0; i < num_blocks + 1; i++) {
sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset. std::memcpy(&sectorMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
for (int i = 0; i < num_blocks + 1; i++) {
std::memcpy(&sectorMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
}
} }
u32 ent_size = 0; u32 ent_size = 0;
@ -312,8 +279,8 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
} }
} }
// let's deal with the root/uroot entries here. // let's deal with the root/uroot enteries here.
// Sometimes it's more than 2 entries (Tomb Raider Remastered) // Sometimes it's more than 2 enteries (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;
@ -329,15 +296,7 @@ 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)
auto parent_path = extract_path.parent_path(); extractPaths[ndinode_counter] = extract_path.parent_path() / GetTitleID();
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;
} }

View File

@ -149,6 +149,7 @@ 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;

View File

@ -1,75 +1,16 @@
// 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 PlaygoFile::Open(const std::filesystem::path& filepath) { bool PlaygoChunk::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()) {
file.Read(playgoHeader); return false;
if (LoadChunks(file)) {
return true;
}
} }
return false; file.Read(playgoHeader);
}
bool PlaygoFile::LoadChunks(const Common::FS::IOFile& file) { return true;
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;
} }

View File

@ -3,129 +3,29 @@
#pragma once #pragma once
#include <filesystem> #include <filesystem>
#include <mutex> #include "common/types.h"
#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; // [0;1] u16 image_count;
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;
u64 language_mask; u16 scenario_count;
u32 mchunks_offset; //<-chunk_mchunks // TODO fill the rest
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:
bool initialized; PlaygoChunk() = default;
OrbisPlayGoHandle handle; ~PlaygoChunk() = default;
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);
bool LoadChunks(const Common::FS::IOFile& file); PlaygoHeader GetPlaygoHeader() {
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; };
};

View File

@ -9,7 +9,7 @@ PSF::PSF() = default;
PSF::~PSF() = default; PSF::~PSF() = default;
bool PSF::open(const std::string& filepath, const std::vector<u8>& psfBuffer) { bool PSF::open(const std::string& filepath, std::vector<u8> psfBuffer) {
if (!psfBuffer.empty()) { if (!psfBuffer.empty()) {
psf.resize(psfBuffer.size()); psf.resize(psfBuffer.size());
psf = psfBuffer; psf = psfBuffer;

View File

@ -35,7 +35,7 @@ public:
PSF(); PSF();
~PSF(); ~PSF();
bool open(const std::string& filepath, const std::vector<u8>& psfBuffer); bool open(const std::string& filepath, 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);

View File

@ -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 (!NeedsCaseInsensitiveSearch) { if (!NeedsCaseInsensiveSearch) {
return host_path; return host_path;
} }

View File

@ -14,9 +14,9 @@ namespace Core::FileSys {
class MntPoints { class MntPoints {
#ifdef _WIN64 #ifdef _WIN64
static constexpr bool NeedsCaseInsensitiveSearch = false; static constexpr bool NeedsCaseInsensiveSearch = false;
#else #else
static constexpr bool NeedsCaseInsensitiveSearch = true; static constexpr bool NeedsCaseInsensiveSearch = true;
#endif #endif
public: public:
struct MntPair { struct MntPair {

View File

@ -1,10 +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 "ajm.h" // Generated By moduleGenerator
#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"

View File

@ -1,28 +0,0 @@
// 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;

View File

@ -1,38 +1,20 @@
// 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;
@ -53,31 +35,9 @@ int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadSp() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentAddcontMount(u32 service_label, int PS4_SYSV_ABI sceAppContentAddcontMount() {
const OrbisNpUnifiedEntitlementLabel* entitlement_label, LOG_ERROR(Lib_AppContent, "(STUBBED) called");
OrbisAppContentMountPoint* mount_point) { return ORBIS_OK;
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_APP_CONTENT_ERROR_NOT_FOUND;
} }
int PS4_SYSV_ABI sceAppContentAddcontShrink() { int PS4_SYSV_ABI sceAppContentAddcontShrink() {
@ -164,80 +124,22 @@ int PS4_SYSV_ABI sceAppContentGetAddcontDownloadProgress() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label, int PS4_SYSV_ABI sceAppContentGetAddcontInfo() {
const OrbisNpUnifiedEntitlementLabel* entitlementLabel, LOG_ERROR(Lib_AppContent, "(STUBBED) called");
OrbisAppContentAddcontInfo* info) { return ORBIS_OK;
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_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) {
LOG_INFO(Lib_AppContent, "called"); *hit_num = 0;
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;
}
int dlcs_to_list = addcont_count < list_num ? addcont_count : list_num;
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( int PS4_SYSV_ABI sceAppContentGetEntitlementKey() {
u32 service_label, const OrbisNpUnifiedEntitlementLabel* entitlement_label, LOG_ERROR(Lib_AppContent, "(STUBBED) called");
OrbisAppContentGetEntitlementKey* key) { return ORBIS_OK;
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() {
@ -248,25 +150,7 @@ 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");
auto* param_sfo = Common::Singleton<PSF>::Instance(); bootParam->attr = 0; // always 0
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;
} }
@ -337,12 +221,12 @@ int PS4_SYSV_ABI Func_C59A36FF8D7C59DA() {
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlementId() { int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlemetId() {
LOG_ERROR(Lib_AppContent, "(STUBBED) called"); LOG_ERROR(Lib_AppContent, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlementId() { int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlemetId() {
LOG_ERROR(Lib_AppContent, "(STUBBED) called"); LOG_ERROR(Lib_AppContent, "(STUBBED) called");
return ORBIS_OK; return ORBIS_OK;
} }
@ -429,9 +313,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,
sceAppContentAddcontEnqueueDownloadByEntitlementId); sceAppContentAddcontEnqueueDownloadByEntitlemetId);
LIB_FUNCTION("efX3lrPwdKA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1, LIB_FUNCTION("efX3lrPwdKA", "libSceAppContentIro", 1, "libSceAppContent", 1, 1,
sceAppContentAddcontMountByEntitlementId); sceAppContentAddcontMountByEntitlemetId);
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,
@ -440,4 +324,4 @@ void RegisterlibSceAppContent(Core::Loader::SymbolsResolver* sym) {
sceAppContentGetDownloadedStoreCountry); sceAppContentGetDownloadedStoreCountry);
}; };
} // namespace Libraries::AppContent } // namespace Libraries::AppContent

View File

@ -41,16 +41,6 @@ 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];
@ -64,17 +54,11 @@ 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(u32 service_label, int PS4_SYSV_ABI sceAppContentAddcontMount();
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);
@ -86,15 +70,11 @@ 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(u32 service_label, int PS4_SYSV_ABI sceAppContentGetAddcontInfo();
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);
@ -112,8 +92,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 sceAppContentAddcontEnqueueDownloadByEntitlementId(); int PS4_SYSV_ABI sceAppContentAddcontEnqueueDownloadByEntitlemetId();
int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlementId(); int PS4_SYSV_ABI sceAppContentAddcontMountByEntitlemetId();
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();

View File

@ -2,10 +2,9 @@
// 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"

View File

@ -40,11 +40,9 @@ 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;
} }
@ -259,7 +257,6 @@ 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();
@ -325,4 +322,4 @@ void RegisterlibSceAvPlayer(Core::Loader::SymbolsResolver* sym) {
LIB_FUNCTION("yN7Jhuv8g24", "libSceAvPlayer", 1, "libSceAvPlayer", 1, 0, sceAvPlayerVprintf); LIB_FUNCTION("yN7Jhuv8g24", "libSceAvPlayer", 1, "libSceAvPlayer", 1, 0, sceAvPlayerVprintf);
}; };
} // namespace Libraries::AvPlayer } // namespace Libraries::AvPlayer

View File

@ -7,8 +7,6 @@
#include "common/types.h" #include "common/types.h"
#include <string_view>
struct AVIOContext; struct AVIOContext;
namespace Libraries::AvPlayer { namespace Libraries::AvPlayer {
@ -16,7 +14,6 @@ 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;
}; };

View File

@ -18,8 +18,19 @@ extern "C" {
namespace Libraries::AvPlayer { namespace Libraries::AvPlayer {
AvPlayerFileStreamer::AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement) AvPlayerFileStreamer::AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement,
: m_file_replacement(file_replacement) {} std::string_view path)
: 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) {
@ -32,21 +43,6 @@ 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) {

View File

@ -15,11 +15,9 @@ namespace Libraries::AvPlayer {
class AvPlayerFileStreamer : public IDataStreamer { class AvPlayerFileStreamer : public IDataStreamer {
public: public:
AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement); AvPlayerFileStreamer(const SceAvPlayerFileReplacement& file_replacement, std::string_view path);
~AvPlayerFileStreamer(); ~AvPlayerFileStreamer();
bool Init(std::string_view path) override;
AVIOContext* GetContext() override { AVIOContext* GetContext() override {
return m_avio_context; return m_avio_context;
} }

View File

@ -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 (!m_state->AddSource(path, GetSourceType(path))) { if (AVPLAYER_IS_ERROR(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 (!m_state->GetStreamInfo(stream_index, info)) { if (AVPLAYER_IS_ERROR(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,10 +145,7 @@ s32 AvPlayer::EnableStream(u32 stream_index) {
} }
s32 AvPlayer::Start() { s32 AvPlayer::Start() {
if (!m_state->Start()) { return m_state->Start();
return ORBIS_AVPLAYER_ERROR_OPERATION_FAILED;
}
return ORBIS_OK;
} }
bool AvPlayer::GetVideoData(SceAvPlayerFrameInfo& video_info) { bool AvPlayer::GetVideoData(SceAvPlayerFrameInfo& video_info) {

View File

@ -5,7 +5,6 @@
#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"
@ -24,37 +23,29 @@ namespace Libraries::AvPlayer {
using namespace Kernel; using namespace Kernel;
AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state) : m_state(state) {} AvPlayerSource::AvPlayerSource(AvPlayerStateCallback& state, std::string_view path,
const SceAvPlayerInitData& init_data,
AvPlayerSource::~AvPlayerSource() { SceAvPlayerSourceType source_type)
Stop(); : 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)) {
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(); AVFormatContext* context = avformat_alloc_context();
if (init_data.file_replacement.open != nullptr) { if (init_data.file_replacement.open != nullptr) {
m_up_data_streamer = std::make_unique<AvPlayerFileStreamer>(init_data.file_replacement); m_up_data_streamer =
if (!m_up_data_streamer->Init(path)) { std::make_unique<AvPlayerFileStreamer>(init_data.file_replacement, path);
return false;
}
context->pb = m_up_data_streamer->GetContext(); context->pb = m_up_data_streamer->GetContext();
if (AVPLAYER_IS_ERROR(avformat_open_input(&context, nullptr, nullptr, nullptr))) { ASSERT(!AVPLAYER_IS_ERROR(avformat_open_input(&context, nullptr, nullptr, nullptr)));
return false;
}
} else { } else {
const auto mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance(); const auto mnt = Common::Singleton<Core::FileSys::MntPoints>::Instance();
const auto filepath = mnt->GetHostPath(path); const auto filepath = mnt->GetHostPath(path);
if (AVPLAYER_IS_ERROR( ASSERT(!AVPLAYER_IS_ERROR(
avformat_open_input(&context, filepath.string().c_str(), nullptr, nullptr))) { avformat_open_input(&context, filepath.string().c_str(), nullptr, nullptr)));
return false;
}
} }
m_avformat_context = AVFormatContextPtr(context, &ReleaseAVFormatContext); m_avformat_context = AVFormatContextPtr(context, &ReleaseAVFormatContext);
return true; }
AvPlayerSource::~AvPlayerSource() {
Stop();
} }
bool AvPlayerSource::FindStreamInfo() { bool AvPlayerSource::FindStreamInfo() {
@ -91,20 +82,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;
} }
bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) { s32 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 false; return -1;
} }
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 false; return -1;
} }
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;
@ -120,8 +111,8 @@ bool 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 = Common::AlignUp(u32(p_stream->codecpar->width), 16); info.details.video.width = p_stream->codecpar->width;
info.details.video.height = Common::AlignUp(u32(p_stream->codecpar->height), 16); info.details.video.height = p_stream->codecpar->height;
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)));
@ -148,9 +139,9 @@ bool 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 false; return -1;
} }
return true; return 0;
} }
bool AvPlayerSource::EnableStream(u32 stream_index) { bool AvPlayerSource::EnableStream(u32 stream_index) {
@ -176,9 +167,8 @@ 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 = Common::AlignUp(u32(m_video_codec_context->width), 16); const auto width = m_video_codec_context->width;
const auto height = Common::AlignUp(u32(m_video_codec_context->height), 16); const auto size = (width * m_video_codec_context->height * 3) / 2;
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));
} }
@ -223,12 +213,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;
} }
bool AvPlayerSource::Start() { s32 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 false; return -1;
} }
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 =
@ -236,7 +226,7 @@ bool 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 true; return 0;
} }
bool AvPlayerSource::Stop() { bool AvPlayerSource::Stop() {
@ -294,6 +284,11 @@ 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;
@ -364,16 +359,12 @@ 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();
} }
@ -498,17 +489,13 @@ 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),
nv12_frame->width, nv12_frame->height, AV_PIX_FMT_NV12, frame.width, frame.height, AV_PIX_FMT_NV12,
SWS_FAST_BILINEAR, nullptr, nullptr, nullptr), SWS_FAST_BILINEAR, nullptr, nullptr, nullptr),
&ReleaseSWSContext); &ReleaseSWSContext);
} }
@ -521,26 +508,6 @@ 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);
@ -554,9 +521,6 @@ 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 =
@ -567,14 +531,9 @@ Frame AvPlayerSource::PrepareVideoFrame(FrameBuffer buffer, const AVFrame& frame
{ {
.video = .video =
{ {
.width = u32(width), .width = u32(frame.width),
.height = u32(height), .height = u32(frame.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,
@ -696,7 +655,6 @@ 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),
}, },
}, },

View File

@ -120,17 +120,17 @@ private:
class AvPlayerSource { class AvPlayerSource {
public: public:
AvPlayerSource(AvPlayerStateCallback& state); AvPlayerSource(AvPlayerStateCallback& state, std::string_view path,
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();
bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info); s32 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);
bool Start(); s32 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);

View File

@ -24,7 +24,6 @@ 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) {
@ -33,10 +32,7 @@ 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{};
if (!self->GetStreamInfo(stream_index, info)) { 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));
@ -120,28 +116,23 @@ AvPlayerState::~AvPlayerState() {
} }
// Called inside GAME thread // Called inside GAME thread
bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType source_type) { s32 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 false; return -1;
} }
{ {
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 false; return -1;
} }
m_up_source = std::make_unique<AvPlayerSource>(*this); m_up_source = std::make_unique<AvPlayerSource>(*this, path, m_init_data, source_type);
if (!m_up_source->Init(m_init_data, path)) {
SetState(AvState::Error);
m_up_source.reset();
return false;
}
} }
AddSourceEvent(); AddSourceEvent();
return true; return 0;
} }
// Called inside GAME thread // Called inside GAME thread
@ -155,25 +146,25 @@ s32 AvPlayerState::GetStreamCount() {
} }
// Called inside GAME thread // Called inside GAME thread
bool AvPlayerState::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info) { s32 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 false; return -1;
} }
return m_up_source->GetStreamInfo(stream_index, info); return m_up_source->GetStreamInfo(stream_index, info);
} }
// Called inside GAME thread // Called inside GAME thread
bool AvPlayerState::Start() { s32 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()) { if (m_up_source == nullptr || m_up_source->Start() < 0) {
LOG_ERROR(Lib_AvPlayer, "Could not start playback."); LOG_ERROR(Lib_AvPlayer, "Could not start playback.");
return false; return -1;
} }
SetState(AvState::Play); SetState(AvState::Play);
OnPlaybackStateChanged(AvState::Play); OnPlaybackStateChanged(AvState::Play);
return true; return 0;
} }
void AvPlayerState::AvControllerThread(std::stop_token stop) { void AvPlayerState::AvControllerThread(std::stop_token stop) {
@ -228,14 +219,11 @@ 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 true; return m_up_source->Stop();
} }
bool AvPlayerState::GetVideoData(SceAvPlayerFrameInfo& video_info) { bool AvPlayerState::GetVideoData(SceAvPlayerFrameInfo& video_info) {

View File

@ -24,11 +24,11 @@ public:
AvPlayerState(const SceAvPlayerInitData& init_data); AvPlayerState(const SceAvPlayerInitData& init_data);
~AvPlayerState(); ~AvPlayerState();
bool AddSource(std::string_view filename, SceAvPlayerSourceType source_type); s32 AddSource(std::string_view filename, SceAvPlayerSourceType source_type);
s32 GetStreamCount(); s32 GetStreamCount();
bool GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info); s32 GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info);
bool EnableStream(u32 stream_index); bool EnableStream(u32 stream_index);
bool Start(); s32 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);

View File

@ -1,6 +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
// 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"

View File

@ -1,6 +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
// 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"

View File

@ -1,6 +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
// 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"

View File

@ -233,6 +233,9 @@ 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
@ -246,6 +249,14 @@ 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;
@ -461,5 +472,3 @@ 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;

View File

@ -1,85 +0,0 @@
// 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;

View File

@ -1,9 +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
#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"
@ -12,6 +9,7 @@
#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"
@ -57,10 +55,6 @@ 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,
@ -100,13 +94,9 @@ 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 + 2); static_assert(InitSequence.size() == 0x73);
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,
@ -146,13 +136,9 @@ 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 + 2); static_assert(InitSequence175.size() == 0x73);
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,
@ -193,13 +179,9 @@ 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 + 2); static_assert(InitSequence200.size() == 0x76);
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,
@ -242,7 +224,7 @@ static constexpr std::array InitSequence350{
0xc0017900u, 0x200u, 0xe0000000u, 0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x2aau, 0xffu, 0xc0016900u, 0x2aau, 0xffu,
}; };
static_assert(InitSequence350.size() == 0x7c + 2); static_assert(InitSequence350.size() == 0x7c);
static constexpr std::array CtxInitSequence{ static constexpr std::array CtxInitSequence{
0xc0012800u, 0x80000000u, 0x80000000u, 0xc0012800u, 0x80000000u, 0x80000000u,
@ -650,12 +632,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_sgpr_offset, u32 vertex_sgpr_offset, u32 instance_vgpr_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_sgpr_offset < 0x10u)) { (vertex_sgpr_offset < 0x10u) && (instance_vgpr_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>(
@ -665,7 +647,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_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[3] = 0; cmdbuf[3] = 0;
cmdbuf += 4; cmdbuf += 4;
@ -707,11 +689,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_sgpr_offset, u32 flags) { u32 vertex_sgpr_offset, u32 instance_vgpr_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_sgpr_offset < 0x10u)) { (vertex_sgpr_offset < 0x10u) && (instance_vgpr_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,
@ -721,7 +703,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_sgpr_offset == 0 ? 0 : (instance_sgpr_offset & 0xffffu) + sgpr_offset; cmdbuf[2] = instance_vgpr_offset == 0 ? 0 : (instance_vgpr_offset & 0xffffu) + sgpr_offset;
cmdbuf[3] = 2; // auto index cmdbuf[3] = 2; // auto index
cmdbuf += 4; cmdbuf += 4;
@ -753,11 +735,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, &InitSequence[2], (InitSequence.size() - 2) * 4); std::memcpy(cmdbuf, InitSequence.data(), InitSequence.size() * 4);
cmdbuf += InitSequence.size() - 2; cmdbuf += InitSequence.size();
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - (InitSequence.size() - 2) - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - InitSequence.size() - (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);
@ -775,10 +757,10 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
} }
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
std::memcpy(cmdbuf, &InitSequence175[2], (InitSequence175.size() - 2) * 4); std::memcpy(cmdbuf, InitSequence175.data(), InitSequence175.size() * 4);
cmdbuf += InitSequence175.size() - 2; cmdbuf += InitSequence175.size();
constexpr auto cmdbuf_left = HwInitPacketSize - (InitSequence175.size() - 2) - 0xc - 1; constexpr auto cmdbuf_left = HwInitPacketSize - InitSequence175.size() - 0xc - 1;
WriteTrailingNop<cmdbuf_left>(cmdbuf); WriteTrailingNop<cmdbuf_left>(cmdbuf);
return HwInitPacketSize; return HwInitPacketSize;
@ -796,11 +778,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, &InitSequence200[2], (InitSequence200.size() - 2) * 4); std::memcpy(cmdbuf, InitSequence200.data(), InitSequence200.size() * 4);
cmdbuf += InitSequence200.size() - 2; cmdbuf += InitSequence200.size();
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - (InitSequence200.size() - 2) - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - InitSequence200.size() - (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);
@ -822,11 +804,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, &InitSequence350[2], (InitSequence350.size() - 2) * 4); std::memcpy(cmdbuf, InitSequence350.data(), InitSequence350.size() * 4);
cmdbuf += InitSequence350.size() - 2; cmdbuf += InitSequence350.size();
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - (InitSequence350.size() - 2) - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - InitSequence350.size() - (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);
@ -1761,7 +1743,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

View File

@ -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_sgpr_offset, u32 vertex_sgpr_offset, u32 instance_vgpr_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_sgpr_offset, u32 flags); u32 vertex_sgpr_offset, u32 instance_vgpr_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);

View File

@ -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"

View File

@ -2,7 +2,6 @@
// 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"

View File

@ -2,10 +2,8 @@
// 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 {

View File

@ -2,7 +2,6 @@
// 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"

View File

@ -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 should be equal to open function posix_open); // _open shoudld be equal to open function
} }
} // namespace Libraries::Kernel } // namespace Libraries::Kernel

View File

@ -4,7 +4,6 @@
#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 {

View File

@ -2,7 +2,6 @@
// 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"
@ -16,8 +15,7 @@ namespace Libraries::Kernel {
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() { u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
LOG_WARNING(Kernel_Vmm, "called"); LOG_WARNING(Kernel_Vmm, "called");
const auto* memory = Core::Memory::Instance(); return SCE_KERNEL_MAIN_DMEM_SIZE;
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,
@ -54,8 +52,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) {
const auto searchEnd = static_cast<s64>(sceKernelGetDirectMemorySize()); return sceKernelAllocateDirectMemory(0, SCE_KERNEL_MAIN_DMEM_SIZE, len, alignment, memoryType,
return sceKernelAllocateDirectMemory(0, searchEnd, len, alignment, memoryType, physAddrOut); physAddrOut);
} }
s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len) { s32 PS4_SYSV_ABI sceKernelCheckedReleaseDirectMemory(u64 start, size_t len) {
@ -77,28 +75,19 @@ 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 (physAddrOut == nullptr || sizeOut == nullptr) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (searchEnd > sceKernelGetDirectMemorySize()) {
return ORBIS_KERNEL_ERROR_EINVAL;
}
if (searchEnd <= searchStart) { if (searchEnd <= searchStart) {
return ORBIS_KERNEL_ERROR_ENOMEM; return ORBIS_KERNEL_ERROR_EINVAL;
}
if (searchEnd > SCE_KERNEL_MAIN_DMEM_SIZE) {
return ORBIS_KERNEL_ERROR_EINVAL;
} }
auto* memory = Core::Memory::Instance(); auto* memory = Core::Memory::Instance();
PAddr physAddr{}; PAddr physAddr;
size_t size{}; s32 result =
s32 result = memory->DirectQueryAvailable(searchStart, searchEnd, alignment, &physAddr, &size); memory->DirectQueryAvailable(searchStart, searchEnd, alignment, &physAddr, sizeOut);
if (size == 0) {
return ORBIS_KERNEL_ERROR_ENOMEM;
}
*physAddrOut = static_cast<u64>(physAddr); *physAddrOut = static_cast<u64>(physAddr);
*sizeOut = size;
return result; return result;
} }
@ -256,56 +245,46 @@ 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;
for (int i = 0; i < numEntries; i++, processed++) { int result = 0;
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.
} }
switch (entries[i].operation) { if (entries[i].operation == MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_DIRECT) {
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(Kernel_Vmm, LOG_INFO(
"entry = {}, operation = {}, len = {:#x}, offset = {:#x}, type = {}, " Kernel_Vmm,
"result = {}", "BatchMap: entry = {}, operation = {}, len = {:#x}, offset = {:#x}, type = {}, "
i, entries[i].operation, entries[i].length, entries[i].offset, "result = {}",
(u8)entries[i].type, result); i, entries[i].operation, entries[i].length, entries[i].offset, (u8)entries[i].type,
break; result);
}
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_UNMAP: { if (result == 0)
processed++;
} 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, "entry = {}, operation = {}, len = {:#x}, result = {}", i, LOG_INFO(Kernel_Vmm, "BatchMap: entry = {}, operation = {}, len = {:#x}, result = {}",
entries[i].operation, entries[i].length, result); i, entries[i].operation, entries[i].length, result);
break;
} if (result == 0)
case MemoryOpTypes::ORBIS_KERNEL_MAP_OP_MAP_FLEXIBLE: { processed++;
} 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,
"entry = {}, operation = {}, len = {:#x}, type = {}, " "BatchMap: 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 != ORBIS_OK) { if (result == 0)
break; processed++;
} 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.

View File

@ -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 = 5056_MB; // ~ 5GB constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 6_GB; // ~ 6GB
namespace Libraries::Kernel { namespace Libraries::Kernel {

View File

@ -2,16 +2,14 @@
// 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"
@ -512,24 +510,23 @@ 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 ORBIS_PTHREAD_MUTEX_ERRORCHECK: case 1:
ptype = PTHREAD_MUTEX_ERRORCHECK; ptype = PTHREAD_MUTEX_ERRORCHECK;
break; break;
case ORBIS_PTHREAD_MUTEX_RECURSIVE: case 2:
ptype = PTHREAD_MUTEX_RECURSIVE; ptype = PTHREAD_MUTEX_RECURSIVE;
break; break;
case ORBIS_PTHREAD_MUTEX_NORMAL: case 3:
case ORBIS_PTHREAD_MUTEX_ADAPTIVE: case 4:
ptype = PTHREAD_MUTEX_NORMAL; ptype = PTHREAD_MUTEX_NORMAL;
break; break;
default: default:
return SCE_KERNEL_ERROR_EINVAL; UNREACHABLE_MSG("Invalid type: {}", type);
} }
int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype); int result = pthread_mutexattr_settype(&(*attr)->pth_mutex_attr, ptype);
ASSERT(result == 0);
return SCE_OK; return result == 0 ? SCE_OK : SCE_KERNEL_ERROR_EINVAL;
} }
int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol) { int PS4_SYSV_ABI scePthreadMutexattrSetprotocol(ScePthreadMutexattr* attr, int protocol) {
@ -987,7 +984,6 @@ static void cleanup_thread(void* arg) {
destructor(value); destructor(value);
} }
} }
Core::CleanupThreadPatchStack();
thread->is_almost_done = true; thread->is_almost_done = true;
} }
@ -995,7 +991,6 @@ 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;
@ -1128,6 +1123,7 @@ 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;
} }
@ -1378,97 +1374,90 @@ 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(PthreadSemInternal** sem, int pshared, unsigned int value) { int PS4_SYSV_ABI posix_sem_init(sem_t* sem, int pshared, unsigned int value) {
if (value > ORBIS_KERNEL_SEM_VALUE_MAX) { int result = sem_init(sem, pshared, value);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
if (sem != nullptr) { return result;
*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(PthreadSemInternal** sem) { int PS4_SYSV_ABI posix_sem_wait(sem_t* sem) {
if (sem == nullptr || *sem == nullptr) { int result = sem_wait(sem);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
(*sem)->semaphore.acquire(); return result;
--(*sem)->value;
return 0;
} }
int PS4_SYSV_ABI posix_sem_trywait(PthreadSemInternal** sem) { int PS4_SYSV_ABI posix_sem_trywait(sem_t* sem) {
if (sem == nullptr || *sem == nullptr) { int result = sem_trywait(sem);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
if (!(*sem)->semaphore.try_acquire()) { return result;
SetPosixErrno(EAGAIN);
return -1;
}
--(*sem)->value;
return 0;
} }
int PS4_SYSV_ABI posix_sem_timedwait(PthreadSemInternal** sem, const timespec* t) { #ifndef HAVE_SEM_TIMEDWAIT
if (sem == nullptr || *sem == nullptr) { int sem_timedwait(sem_t* sem, const struct timespec* abstime) {
SetPosixErrno(EINVAL); int rc;
return -1; while ((rc = sem_trywait(sem)) == EAGAIN) {
} struct timespec curr_time;
clock_gettime(CLOCK_REALTIME, &curr_time);
using std::chrono::duration_cast; s64 remaining_ns = 0;
using std::chrono::nanoseconds; remaining_ns +=
using std::chrono::seconds; (static_cast<s64>(abstime->tv_sec) - static_cast<s64>(curr_time.tv_sec)) * 1000000000L;
using std::chrono::system_clock; remaining_ns += static_cast<s64>(abstime->tv_nsec) - static_cast<s64>(curr_time.tv_nsec);
const system_clock::time_point time{ if (remaining_ns <= 0) {
duration_cast<system_clock::duration>(seconds{t->tv_sec} + nanoseconds{t->tv_nsec})}; return ETIMEDOUT;
if (!(*sem)->semaphore.try_acquire_until(time)) { }
SetPosixErrno(ETIMEDOUT);
return -1; struct timespec sleep_time;
sleep_time.tv_sec = 0;
if (remaining_ns < 5000000L) {
sleep_time.tv_nsec = remaining_ns;
} else {
sleep_time.tv_nsec = 5000000;
}
nanosleep(&sleep_time, nullptr);
} }
--(*sem)->value; return rc;
return 0; }
#endif
int PS4_SYSV_ABI posix_sem_timedwait(sem_t* sem, const timespec* t) {
int result = sem_timedwait(sem, t);
if (result == -1) {
SetPosixErrno(errno);
}
return result;
} }
int PS4_SYSV_ABI posix_sem_post(PthreadSemInternal** sem) { int PS4_SYSV_ABI posix_sem_post(sem_t* sem) {
if (sem == nullptr || *sem == nullptr) { int result = sem_post(sem);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
if ((*sem)->value == ORBIS_KERNEL_SEM_VALUE_MAX) { return result;
SetPosixErrno(EOVERFLOW);
return -1;
}
++(*sem)->value;
(*sem)->semaphore.release();
return 0;
} }
int PS4_SYSV_ABI posix_sem_destroy(PthreadSemInternal** sem) { int PS4_SYSV_ABI posix_sem_destroy(sem_t* sem) {
if (sem == nullptr || *sem == nullptr) { int result = sem_destroy(sem);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
delete *sem; return result;
*sem = nullptr;
return 0;
} }
int PS4_SYSV_ABI posix_sem_getvalue(PthreadSemInternal** sem, int* sval) { int PS4_SYSV_ABI posix_sem_getvalue(sem_t* sem, int* sval) {
if (sem == nullptr || *sem == nullptr) { int result = sem_getvalue(sem, sval);
SetPosixErrno(EINVAL); if (result == -1) {
return -1; SetPosixErrno(errno);
} }
if (sval) { return result;
*sval = (*sem)->value;
}
return 0;
} }
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) {

View File

@ -5,12 +5,10 @@
#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 {
@ -21,12 +19,6 @@ 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;
@ -112,11 +104,6 @@ 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();

View File

@ -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,6 +13,9 @@
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)
@ -34,7 +37,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);
@ -49,14 +52,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;
@ -67,9 +70,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;
@ -77,7 +80,7 @@ public:
} }
public: public:
struct WaitingThread { struct WaitingThread : public ListBaseHook {
std::condition_variable cv; std::condition_variable cv;
u32 priority; u32 priority;
s32 need_count; s32 need_count;
@ -129,7 +132,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);
@ -137,13 +140,16 @@ 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);
} }
std::list<WaitingThread*> wait_list; using WaitingThreads =
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;

View File

@ -2,9 +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 "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"
@ -32,8 +30,7 @@ u64 PS4_SYSV_ABI sceKernelGetTscFrequency() {
} }
u64 PS4_SYSV_ABI sceKernelGetProcessTime() { u64 PS4_SYSV_ABI sceKernelGetProcessTime() {
// TODO: this timer should support suspends, so initial ptc needs to be updated on wake up return clock->GetProcessTimeUS();
return clock->GetTimeUS(initial_ptc);
} }
u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() { u64 PS4_SYSV_ABI sceKernelGetProcessTimeCounter() {

View File

@ -0,0 +1,496 @@
// 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

View File

@ -0,0 +1,14 @@
// 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

View File

@ -0,0 +1,161 @@
// 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

View File

@ -0,0 +1,15 @@
// 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

View File

@ -0,0 +1,55 @@
// 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

View File

@ -0,0 +1,21 @@
// 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