mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-06 19:01:52 +03:00
Compare commits
No commits in common. "main" and "v.0.7.0" have entirely different histories.
305 changed files with 12019 additions and 15799 deletions
21
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
21
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
|
@ -53,24 +53,3 @@ body:
|
||||||
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
|
||||||
id: cpu
|
|
||||||
attributes:
|
|
||||||
label: CPU
|
|
||||||
placeholder: "Example: Intel Core i7-8700"
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: gpu
|
|
||||||
attributes:
|
|
||||||
label: GPU
|
|
||||||
placeholder: "Example: nVidia GTX 1650"
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
- type: input
|
|
||||||
id: ram
|
|
||||||
attributes:
|
|
||||||
label: Amount of RAM in GB
|
|
||||||
placeholder: "Example: 16 GB"
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
34
.github/workflows/build.yml
vendored
34
.github/workflows/build.yml
vendored
|
@ -30,7 +30,7 @@ jobs:
|
||||||
- name: Install
|
- name: Install
|
||||||
run: |
|
run: |
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||||
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
|
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-19 main'
|
||||||
sudo apt update
|
sudo apt update
|
||||||
sudo apt install clang-format-19
|
sudo apt install clang-format-19
|
||||||
- name: Build
|
- name: Build
|
||||||
|
@ -205,12 +205,12 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
mkdir upload
|
mkdir upload
|
||||||
mv ${{github.workspace}}/build/shadps4 upload
|
mv ${{github.workspace}}/build/shadps4 upload
|
||||||
mv ${{github.workspace}}/build/MoltenVK_icd.json upload
|
cp ${{github.workspace}}/build/externals/MoltenVK/libMoltenVK.dylib upload
|
||||||
mv ${{github.workspace}}/build/libMoltenVK.dylib upload
|
tar cf shadps4-macos-sdl.tar.gz -C upload .
|
||||||
- uses: actions/upload-artifact@v4
|
- uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: shadps4-macos-sdl-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
|
name: shadps4-macos-sdl-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
|
||||||
path: upload/
|
path: shadps4-macos-sdl.tar.gz
|
||||||
|
|
||||||
macos-qt:
|
macos-qt:
|
||||||
runs-on: macos-15
|
runs-on: macos-15
|
||||||
|
@ -281,13 +281,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Add LLVM repository
|
|
||||||
run: |
|
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
|
||||||
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang-19 mold build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
@ -309,7 +304,7 @@ jobs:
|
||||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||||
|
@ -342,13 +337,8 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Add LLVM repository
|
|
||||||
run: |
|
|
||||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
|
||||||
sudo add-apt-repository 'deb http://apt.llvm.org/noble/ llvm-toolchain-noble-19 main'
|
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang-19 mold build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 clang build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
@ -370,7 +360,7 @@ jobs:
|
||||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||||
|
@ -395,7 +385,7 @@ jobs:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 mold build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
@ -417,7 +407,7 @@ jobs:
|
||||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||||
|
@ -431,7 +421,7 @@ jobs:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 mold build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
run: sudo apt-get update && sudo apt install -y libx11-dev libxext-dev libwayland-dev libdecor-0-dev libxkbcommon-dev libglfw3-dev libgles2-mesa-dev libfuse2 gcc-14 build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||||
|
|
||||||
- name: Cache CMake Configuration
|
- name: Cache CMake Configuration
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
|
@ -453,7 +443,7 @@ jobs:
|
||||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=gcc-14 -DCMAKE_CXX_COMPILER=g++-14 -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||||
|
|
11
.gitmodules
vendored
11
.gitmodules
vendored
|
@ -1,3 +1,11 @@
|
||||||
|
[submodule "externals/cryptopp-cmake"]
|
||||||
|
path = externals/cryptopp-cmake
|
||||||
|
url = https://github.com/shadps4-emu/ext-cryptopp-cmake.git
|
||||||
|
shallow = true
|
||||||
|
[submodule "externals/cryptopp"]
|
||||||
|
path = externals/cryptopp
|
||||||
|
url = https://github.com/shadps4-emu/ext-cryptopp.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
|
||||||
|
@ -107,6 +115,3 @@
|
||||||
path = externals/MoltenVK/cereal
|
path = externals/MoltenVK/cereal
|
||||||
url = https://github.com/USCiLab/cereal
|
url = https://github.com/USCiLab/cereal
|
||||||
shallow = true
|
shallow = true
|
||||||
[submodule "externals/libusb"]
|
|
||||||
path = externals/libusb
|
|
||||||
url = https://github.com/libusb/libusb-cmake.git
|
|
||||||
|
|
185
CMakeLists.txt
Normal file → Executable file
185
CMakeLists.txt
Normal file → Executable file
|
@ -9,8 +9,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
list(APPEND ADDITIONAL_LANGUAGES OBJC)
|
list(APPEND ADDITIONAL_LANGUAGES OBJC)
|
||||||
# Starting with 15.4, Rosetta 2 has support for all the necessary instruction sets.
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 14)
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 15.4 CACHE STRING "")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
|
@ -54,9 +53,8 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE STREQUAL "x86_64")
|
if (ARCHITECTURE STREQUAL "x86_64")
|
||||||
# Target the same CPU architecture as the PS4, to maintain the same level of compatibility.
|
# Set x86_64 target level to Sandy Bridge to generally match what is supported for PS4 guest code with CPU patches.
|
||||||
# Exclude SSE4a as it is only available on AMD CPUs.
|
add_compile_options(-march=sandybridge)
|
||||||
add_compile_options(-march=btver2 -mtune=generic -mno-sse4a)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE AND ARCHITECTURE STREQUAL "x86_64" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
if (APPLE AND ARCHITECTURE STREQUAL "x86_64" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||||
|
@ -105,81 +103,38 @@ if (CLANG_FORMAT)
|
||||||
unset(CCOMMENT)
|
unset(CCOMMENT)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
# generate git revision information
|
# generate git revision information
|
||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/GetGitRevisionDescription.cmake")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/")
|
||||||
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
git_describe(GIT_DESC --always --long --dirty)
|
git_describe(GIT_DESC --always --long --dirty)
|
||||||
git_branch_name(GIT_BRANCH)
|
git_branch_name(GIT_BRANCH)
|
||||||
string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S")
|
string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S")
|
||||||
|
|
||||||
message("start git things")
|
|
||||||
|
|
||||||
# Try to get the upstream remote and branch
|
# Try to get the upstream remote and branch
|
||||||
message("check for remote and branch")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git rev-parse --abbrev-ref --symbolic-full-name @{u}
|
COMMAND git rev-parse --abbrev-ref --symbolic-full-name @{u}
|
||||||
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
||||||
RESULT_VARIABLE GIT_REMOTE_RESULT
|
RESULT_VARIABLE GIT_BRANCH_RESULT
|
||||||
ERROR_QUIET
|
ERROR_QUIET
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
# If there's no upstream set or the command failed, check remote.pushDefault
|
# If there's no upstream set or the command failed, check remote.pushDefault
|
||||||
if (GIT_REMOTE_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
if (GIT_BRANCH_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||||
message("check default push")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git config --get remote.pushDefault
|
COMMAND git config --get remote.pushDefault
|
||||||
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
||||||
RESULT_VARIABLE GIT_REMOTE_RESULT
|
RESULT_VARIABLE GIT_PUSH_DEFAULT_RESULT
|
||||||
ERROR_QUIET
|
ERROR_QUIET
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
endif()
|
|
||||||
|
|
||||||
# If running in GitHub Actions and the above fails
|
# If remote.pushDefault is not set or fails, default to origin
|
||||||
if (GIT_REMOTE_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
if (GIT_PUSH_DEFAULT_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||||
message("check github")
|
|
||||||
set(GIT_REMOTE_NAME "origin")
|
set(GIT_REMOTE_NAME "origin")
|
||||||
|
|
||||||
# Retrieve environment variables
|
|
||||||
if (DEFINED ENV{GITHUB_HEAD_REF} AND NOT "$ENV{GITHUB_HEAD_REF}" STREQUAL "")
|
|
||||||
message("github head ref: $ENV{GITHUB_HEAD_REF}")
|
|
||||||
set(GITHUB_HEAD_REF "$ENV{GITHUB_HEAD_REF}")
|
|
||||||
else()
|
|
||||||
set(GITHUB_HEAD_REF "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (DEFINED ENV{GITHUB_REF} AND NOT "$ENV{GITHUB_REF}" STREQUAL "")
|
|
||||||
message("github ref: $ENV{GITHUB_REF}")
|
|
||||||
string(REGEX REPLACE "^refs/[^/]*/" "" GITHUB_BRANCH "$ENV{GITHUB_REF}")
|
|
||||||
string(REGEX MATCH "refs/pull/([0-9]+)/merge" MATCHED_REF "$ENV{GITHUB_REF}")
|
|
||||||
if (MATCHED_REF)
|
|
||||||
set(PR_NUMBER "${CMAKE_MATCH_1}")
|
|
||||||
set(GITHUB_BRANCH "")
|
|
||||||
message("PR number: ${PR_NUMBER}")
|
|
||||||
else()
|
|
||||||
set(PR_NUMBER "")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(GITHUB_BRANCH "")
|
|
||||||
set(PR_NUMBER "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT "${PR_NUMBER}" STREQUAL "" AND NOT "${GITHUB_HEAD_REF}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "pr-${PR_NUMBER}-${GITHUB_HEAD_REF}")
|
|
||||||
elseif (NOT "${PR_NUMBER}" STREQUAL "" AND NOT "${GITHUB_BRANCH}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "pr-${PR_NUMBER}-${GITHUB_BRANCH}")
|
|
||||||
elseif (NOT "${PR_NUMBER}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "pr-${PR_NUMBER}")
|
|
||||||
elseif ("${PR_NUMBER}" STREQUAL "" AND NOT "${GITHUB_HEAD_REF}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "${GITHUB_HEAD_REF}")
|
|
||||||
elseif ("${PR_NUMBER}" STREQUAL "" AND NOT "${GITHUB_BRANCH}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "${GITHUB_BRANCH}")
|
|
||||||
elseif ("${PR_NUMBER}" STREQUAL "" AND NOT "${GITHUB_REF}" STREQUAL "")
|
|
||||||
set(GIT_BRANCH "${GITHUB_REF}")
|
|
||||||
else()
|
|
||||||
message("couldn't find branch")
|
|
||||||
set(GIT_BRANCH "detached-head")
|
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
# Extract remote name if the output contains a remote/branch format
|
# Extract remote name if the output contains a remote/branch format
|
||||||
|
@ -193,27 +148,14 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Get remote link
|
# Get remote link
|
||||||
message("getting remote link")
|
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND git config --get remote.${GIT_REMOTE_NAME}.url
|
COMMAND git config --get remote.${GIT_REMOTE_NAME}.url
|
||||||
OUTPUT_VARIABLE GIT_REMOTE_URL
|
OUTPUT_VARIABLE GIT_REMOTE_URL
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
|
|
||||||
# Set Version
|
|
||||||
set(EMULATOR_VERSION_MAJOR "0")
|
|
||||||
set(EMULATOR_VERSION_MINOR "8")
|
|
||||||
set(EMULATOR_VERSION_PATCH "1")
|
|
||||||
|
|
||||||
set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}")
|
|
||||||
|
|
||||||
set(APP_VERSION "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH} WIP")
|
|
||||||
set(APP_IS_RELEASE false)
|
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||||
|
|
||||||
message("end git things, remote: ${GIT_REMOTE_NAME}, branch: ${GIT_BRANCH}")
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
|
||||||
find_package(Boost 1.84.0 CONFIG)
|
find_package(Boost 1.84.0 CONFIG)
|
||||||
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.0 CONFIG)
|
||||||
|
@ -226,18 +168,21 @@ find_package(SDL3 3.1.2 CONFIG)
|
||||||
find_package(stb MODULE)
|
find_package(stb MODULE)
|
||||||
find_package(toml11 4.2.0 CONFIG)
|
find_package(toml11 4.2.0 CONFIG)
|
||||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||||
find_package(VulkanHeaders 1.4.309 CONFIG)
|
find_package(VulkanHeaders 1.4.305 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 1.3 MODULE)
|
find_package(ZLIB 1.3 MODULE)
|
||||||
find_package(Zydis 5.0.0 CONFIG)
|
find_package(Zydis 5.0.0 CONFIG)
|
||||||
find_package(pugixml 1.14 CONFIG)
|
find_package(pugixml 1.14 CONFIG)
|
||||||
find_package(libusb 1.0.27 MODULE)
|
|
||||||
|
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)
|
||||||
endif()
|
endif()
|
||||||
list(POP_BACK CMAKE_MODULE_PATH)
|
|
||||||
|
|
||||||
# Note: Windows always has these functions through winpthreads
|
# Note: Windows always has these functions through winpthreads
|
||||||
include(CheckSymbolExists)
|
include(CheckSymbolExists)
|
||||||
|
@ -340,8 +285,6 @@ set(KERNEL_LIB src/core/libraries/kernel/sync/mutex.cpp
|
||||||
src/core/libraries/kernel/threads/thread_state.h
|
src/core/libraries/kernel/threads/thread_state.h
|
||||||
src/core/libraries/kernel/process.cpp
|
src/core/libraries/kernel/process.cpp
|
||||||
src/core/libraries/kernel/process.h
|
src/core/libraries/kernel/process.h
|
||||||
src/core/libraries/kernel/debug.cpp
|
|
||||||
src/core/libraries/kernel/debug.h
|
|
||||||
src/core/libraries/kernel/equeue.cpp
|
src/core/libraries/kernel/equeue.cpp
|
||||||
src/core/libraries/kernel/equeue.h
|
src/core/libraries/kernel/equeue.h
|
||||||
src/core/libraries/kernel/file_system.cpp
|
src/core/libraries/kernel/file_system.cpp
|
||||||
|
@ -371,19 +314,11 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
||||||
src/core/libraries/network/net_ctl_obj.cpp
|
src/core/libraries/network/net_ctl_obj.cpp
|
||||||
src/core/libraries/network/net_ctl_obj.h
|
src/core/libraries/network/net_ctl_obj.h
|
||||||
src/core/libraries/network/net_ctl_codes.h
|
src/core/libraries/network/net_ctl_codes.h
|
||||||
src/core/libraries/network/net_util.cpp
|
|
||||||
src/core/libraries/network/net_util.h
|
|
||||||
src/core/libraries/network/net_error.h
|
|
||||||
src/core/libraries/network/net.h
|
src/core/libraries/network/net.h
|
||||||
src/core/libraries/network/ssl.cpp
|
src/core/libraries/network/ssl.cpp
|
||||||
src/core/libraries/network/ssl.h
|
src/core/libraries/network/ssl.h
|
||||||
src/core/libraries/network/ssl2.cpp
|
src/core/libraries/network/ssl2.cpp
|
||||||
src/core/libraries/network/ssl2.h
|
src/core/libraries/network/ssl2.h
|
||||||
src/core/libraries/network/sys_net.cpp
|
|
||||||
src/core/libraries/network/sys_net.h
|
|
||||||
src/core/libraries/network/posix_sockets.cpp
|
|
||||||
src/core/libraries/network/p2p_sockets.cpp
|
|
||||||
src/core/libraries/network/sockets.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(AVPLAYER_LIB src/core/libraries/avplayer/avplayer_common.cpp
|
set(AVPLAYER_LIB src/core/libraries/avplayer/avplayer_common.cpp
|
||||||
|
@ -443,28 +378,12 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||||
src/core/libraries/ngs2/ngs2_error.h
|
src/core/libraries/ngs2/ngs2_error.h
|
||||||
src/core/libraries/ngs2/ngs2_impl.cpp
|
src/core/libraries/ngs2/ngs2_impl.cpp
|
||||||
src/core/libraries/ngs2/ngs2_impl.h
|
src/core/libraries/ngs2/ngs2_impl.h
|
||||||
src/core/libraries/ngs2/ngs2_custom.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_custom.h
|
|
||||||
src/core/libraries/ngs2/ngs2_reverb.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_reverb.h
|
|
||||||
src/core/libraries/ngs2/ngs2_geom.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_geom.h
|
|
||||||
src/core/libraries/ngs2/ngs2_pan.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_pan.h
|
|
||||||
src/core/libraries/ngs2/ngs2_report.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_report.h
|
|
||||||
src/core/libraries/ngs2/ngs2_eq.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_eq.h
|
|
||||||
src/core/libraries/ngs2/ngs2_mastering.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_mastering.h
|
|
||||||
src/core/libraries/ngs2/ngs2_sampler.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_sampler.h
|
|
||||||
src/core/libraries/ngs2/ngs2_submixer.cpp
|
|
||||||
src/core/libraries/ngs2/ngs2_submixer.h
|
|
||||||
src/core/libraries/ajm/ajm_error.h
|
src/core/libraries/ajm/ajm_error.h
|
||||||
src/core/libraries/audio3d/audio3d.cpp
|
src/core/libraries/audio3d/audio3d.cpp
|
||||||
src/core/libraries/audio3d/audio3d.h
|
src/core/libraries/audio3d/audio3d.h
|
||||||
src/core/libraries/audio3d/audio3d_error.h
|
src/core/libraries/audio3d/audio3d_error.h
|
||||||
|
src/core/libraries/audio3d/audio3d_impl.cpp
|
||||||
|
src/core/libraries/audio3d/audio3d_impl.h
|
||||||
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
|
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
|
||||||
src/core/libraries/game_live_streaming/gamelivestreaming.h
|
src/core/libraries/game_live_streaming/gamelivestreaming.h
|
||||||
src/core/libraries/remote_play/remoteplay.cpp
|
src/core/libraries/remote_play/remoteplay.cpp
|
||||||
|
@ -578,8 +497,6 @@ set(NP_LIBS src/core/libraries/np_common/np_common.cpp
|
||||||
src/core/libraries/np_web_api/np_web_api.h
|
src/core/libraries/np_web_api/np_web_api.h
|
||||||
src/core/libraries/np_party/np_party.cpp
|
src/core/libraries/np_party/np_party.cpp
|
||||||
src/core/libraries/np_party/np_party.h
|
src/core/libraries/np_party/np_party.h
|
||||||
src/core/libraries/np_auth/np_auth.cpp
|
|
||||||
src/core/libraries/np_auth/np_auth.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ZLIB_LIB src/core/libraries/zlib/zlib.cpp
|
set(ZLIB_LIB src/core/libraries/zlib/zlib.cpp
|
||||||
|
@ -595,8 +512,6 @@ set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
|
||||||
src/core/libraries/screenshot/screenshot.h
|
src/core/libraries/screenshot/screenshot.h
|
||||||
src/core/libraries/move/move.cpp
|
src/core/libraries/move/move.cpp
|
||||||
src/core/libraries/move/move.h
|
src/core/libraries/move/move.h
|
||||||
src/core/libraries/ulobjmgr/ulobjmgr.cpp
|
|
||||||
src/core/libraries/ulobjmgr/ulobjmgr.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(DEV_TOOLS src/core/devtools/layer.cpp
|
set(DEV_TOOLS src/core/devtools/layer.cpp
|
||||||
|
@ -636,7 +551,6 @@ set(COMMON src/common/logging/backend.cpp
|
||||||
src/common/logging/text_formatter.cpp
|
src/common/logging/text_formatter.cpp
|
||||||
src/common/logging/text_formatter.h
|
src/common/logging/text_formatter.h
|
||||||
src/common/logging/types.h
|
src/common/logging/types.h
|
||||||
src/common/aes.h
|
|
||||||
src/common/alignment.h
|
src/common/alignment.h
|
||||||
src/common/arch.h
|
src/common/arch.h
|
||||||
src/common/assert.cpp
|
src/common/assert.cpp
|
||||||
|
@ -668,7 +582,6 @@ set(COMMON src/common/logging/backend.cpp
|
||||||
src/common/polyfill_thread.h
|
src/common/polyfill_thread.h
|
||||||
src/common/rdtsc.cpp
|
src/common/rdtsc.cpp
|
||||||
src/common/rdtsc.h
|
src/common/rdtsc.h
|
||||||
src/common/sha1.h
|
|
||||||
src/common/signal_context.h
|
src/common/signal_context.h
|
||||||
src/common/signal_context.cpp
|
src/common/signal_context.cpp
|
||||||
src/common/singleton.h
|
src/common/singleton.h
|
||||||
|
@ -687,6 +600,7 @@ set(COMMON src/common/logging/backend.cpp
|
||||||
src/common/uint128.h
|
src/common/uint128.h
|
||||||
src/common/unique_function.h
|
src/common/unique_function.h
|
||||||
src/common/va_ctx.h
|
src/common/va_ctx.h
|
||||||
|
src/common/version.h
|
||||||
src/common/ntapi.h
|
src/common/ntapi.h
|
||||||
src/common/ntapi.cpp
|
src/common/ntapi.cpp
|
||||||
src/common/number_utils.h
|
src/common/number_utils.h
|
||||||
|
@ -707,6 +621,9 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||||
src/core/aerolib/aerolib.h
|
src/core/aerolib/aerolib.h
|
||||||
src/core/address_space.cpp
|
src/core/address_space.cpp
|
||||||
src/core/address_space.h
|
src/core/address_space.h
|
||||||
|
src/core/crypto/crypto.cpp
|
||||||
|
src/core/crypto/crypto.h
|
||||||
|
src/core/crypto/keys.h
|
||||||
src/core/devices/base_device.cpp
|
src/core/devices/base_device.cpp
|
||||||
src/core/devices/base_device.h
|
src/core/devices/base_device.h
|
||||||
src/core/devices/ioccom.h
|
src/core/devices/ioccom.h
|
||||||
|
@ -724,6 +641,10 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||||
src/core/devices/srandom_device.cpp
|
src/core/devices/srandom_device.cpp
|
||||||
src/core/devices/srandom_device.h
|
src/core/devices/srandom_device.h
|
||||||
src/core/file_format/pfs.h
|
src/core/file_format/pfs.h
|
||||||
|
src/core/file_format/pkg.cpp
|
||||||
|
src/core/file_format/pkg.h
|
||||||
|
src/core/file_format/pkg_type.cpp
|
||||||
|
src/core/file_format/pkg_type.h
|
||||||
src/core/file_format/psf.cpp
|
src/core/file_format/psf.cpp
|
||||||
src/core/file_format/psf.h
|
src/core/file_format/psf.h
|
||||||
src/core/file_format/playgo_chunk.cpp
|
src/core/file_format/playgo_chunk.cpp
|
||||||
|
@ -732,6 +653,8 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||||
src/core/file_format/trp.h
|
src/core/file_format/trp.h
|
||||||
src/core/file_sys/fs.cpp
|
src/core/file_sys/fs.cpp
|
||||||
src/core/file_sys/fs.h
|
src/core/file_sys/fs.h
|
||||||
|
src/core/loader.cpp
|
||||||
|
src/core/loader.h
|
||||||
src/core/loader/dwarf.cpp
|
src/core/loader/dwarf.cpp
|
||||||
src/core/loader/dwarf.h
|
src/core/loader/dwarf.h
|
||||||
src/core/loader/elf.cpp
|
src/core/loader/elf.cpp
|
||||||
|
@ -848,8 +771,6 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||||
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
|
||||||
src/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp
|
src/shader_recompiler/ir/passes/lower_buffer_format_to_raw.cpp
|
||||||
src/shader_recompiler/ir/passes/lower_fp64_to_fp32.cpp
|
|
||||||
src/shader_recompiler/ir/passes/readlane_elimination_pass.cpp
|
|
||||||
src/shader_recompiler/ir/passes/resource_tracking_pass.cpp
|
src/shader_recompiler/ir/passes/resource_tracking_pass.cpp
|
||||||
src/shader_recompiler/ir/passes/ring_access_elimination.cpp
|
src/shader_recompiler/ir/passes/ring_access_elimination.cpp
|
||||||
src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp
|
src/shader_recompiler/ir/passes/shader_info_collection_pass.cpp
|
||||||
|
@ -1022,6 +943,10 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||||
src/qt_gui/game_grid_frame.h
|
src/qt_gui/game_grid_frame.h
|
||||||
src/qt_gui/game_install_dialog.cpp
|
src/qt_gui/game_install_dialog.cpp
|
||||||
src/qt_gui/game_install_dialog.h
|
src/qt_gui/game_install_dialog.h
|
||||||
|
src/qt_gui/install_dir_select.cpp
|
||||||
|
src/qt_gui/install_dir_select.h
|
||||||
|
src/qt_gui/pkg_viewer.cpp
|
||||||
|
src/qt_gui/pkg_viewer.h
|
||||||
src/qt_gui/trophy_viewer.cpp
|
src/qt_gui/trophy_viewer.cpp
|
||||||
src/qt_gui/trophy_viewer.h
|
src/qt_gui/trophy_viewer.h
|
||||||
src/qt_gui/elf_viewer.cpp
|
src/qt_gui/elf_viewer.cpp
|
||||||
|
@ -1077,7 +1002,7 @@ endif()
|
||||||
create_target_directory_groups(shadps4)
|
create_target_directory_groups(shadps4)
|
||||||
|
|
||||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb)
|
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers cryptopp::cryptopp)
|
||||||
|
|
||||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||||
|
@ -1092,35 +1017,26 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ENABLE_USERFAULTFD)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# Include MoltenVK, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers.
|
|
||||||
if (ENABLE_QT_GUI)
|
if (ENABLE_QT_GUI)
|
||||||
set(MVK_BUNDLE_PATH "Resources/vulkan/icd.d")
|
# Include MoltenVK in the app bundle, along with an ICD file so it can be found by the system Vulkan loader if used for loading layers.
|
||||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../${MVK_BUNDLE_PATH}")
|
set(MVK_ICD ${CMAKE_CURRENT_SOURCE_DIR}/externals/MoltenVK/MoltenVK_icd.json)
|
||||||
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/${MVK_BUNDLE_PATH})
|
target_sources(shadps4 PRIVATE ${MVK_ICD})
|
||||||
else()
|
set_source_files_properties(${MVK_ICD} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/vulkan/icd.d)
|
||||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path")
|
|
||||||
set(MVK_DST ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
|
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
|
||||||
set(MVK_DYLIB_DST ${MVK_DST}/libMoltenVK.dylib)
|
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib)
|
||||||
set(MVK_ICD_SRC ${CMAKE_CURRENT_SOURCE_DIR}/externals/MoltenVK/MoltenVK/MoltenVK/icd/MoltenVK_icd.json)
|
|
||||||
set(MVK_ICD_DST ${MVK_DST}/MoltenVK_icd.json)
|
|
||||||
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${MVK_DST}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${MVK_DST})
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${MVK_ICD_DST}
|
|
||||||
DEPENDS ${MVK_ICD_SRC} ${MVK_DST}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_ICD_SRC} ${MVK_ICD_DST})
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${MVK_DYLIB_DST}
|
OUTPUT ${MVK_DYLIB_DST}
|
||||||
DEPENDS ${MVK_DYLIB_SRC} ${MVK_DST}
|
DEPENDS ${MVK_DYLIB_SRC}
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
|
COMMAND cmake -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
|
||||||
add_custom_target(CopyMoltenVK DEPENDS ${MVK_ICD_DST} ${MVK_DYLIB_DST})
|
add_custom_target(CopyMoltenVK DEPENDS ${MVK_DYLIB_DST})
|
||||||
add_dependencies(CopyMoltenVK MoltenVK)
|
add_dependencies(CopyMoltenVK MoltenVK)
|
||||||
add_dependencies(shadps4 CopyMoltenVK)
|
add_dependencies(shadps4 CopyMoltenVK)
|
||||||
|
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks")
|
||||||
|
else()
|
||||||
|
# For non-bundled SDL build, just do a normal library link.
|
||||||
|
target_link_libraries(shadps4 PRIVATE MoltenVK)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ARCHITECTURE STREQUAL "x86_64")
|
if (ARCHITECTURE STREQUAL "x86_64")
|
||||||
# Reserve system-managed memory space.
|
# Reserve system-managed memory space.
|
||||||
|
@ -1197,7 +1113,7 @@ target_include_directories(shadps4 PRIVATE ${HOST_SHADERS_INCLUDE})
|
||||||
|
|
||||||
# embed resources
|
# embed resources
|
||||||
|
|
||||||
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeRC.cmake")
|
include(CMakeRC)
|
||||||
cmrc_add_resource_library(embedded-resources
|
cmrc_add_resource_library(embedded-resources
|
||||||
ALIAS res::embedded
|
ALIAS res::embedded
|
||||||
NAMESPACE res
|
NAMESPACE res
|
||||||
|
@ -1205,6 +1121,7 @@ cmrc_add_resource_library(embedded-resources
|
||||||
src/images/gold.png
|
src/images/gold.png
|
||||||
src/images/platinum.png
|
src/images/platinum.png
|
||||||
src/images/silver.png)
|
src/images/silver.png)
|
||||||
|
|
||||||
target_link_libraries(shadps4 PRIVATE res::embedded)
|
target_link_libraries(shadps4 PRIVATE res::embedded)
|
||||||
|
|
||||||
# ImGui resources
|
# ImGui resources
|
||||||
|
@ -1218,7 +1135,7 @@ if (ENABLE_QT_GUI)
|
||||||
MACOSX_BUNDLE ON
|
MACOSX_BUNDLE ON
|
||||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in"
|
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in"
|
||||||
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
||||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APP_VERSION}"
|
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.4.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
set_source_files_properties(src/images/shadPS4.icns PROPERTIES
|
set_source_files_properties(src/images/shadPS4.icns PROPERTIES
|
||||||
|
|
36
README.md
36
README.md
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
<a href="https://discord.gg/bFJxfftGW6">
|
<a href="https://discord.gg/bFJxfftGW6">
|
||||||
<img src="https://img.shields.io/discord/1080089157554155590?color=5865F2&label=shadPS4%20Discord&logo=Discord&logoColor=white" width="275">
|
<img src="https://img.shields.io/discord/1080089157554155590?color=5865F2&label=shadPS4 Discord&logo=Discord&logoColor=white" width="240">
|
||||||
<a href="https://github.com/shadps4-emu/shadPS4/releases/latest">
|
<a href="https://github.com/shadps4-emu/shadPS4/releases/latest">
|
||||||
<img src="https://img.shields.io/github/downloads/shadps4-emu/shadPS4/total.svg" width="140">
|
<img src="https://img.shields.io/github/downloads/shadps4-emu/shadPS4/total.svg" width="140">
|
||||||
<a href="https://shadps4.net/">
|
<a href="https://shadps4.net/">
|
||||||
|
@ -71,7 +71,7 @@ Check the build instructions for [**Linux**](https://github.com/shadps4-emu/shad
|
||||||
Check the build instructions for [**macOS**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-macos.md).
|
Check the build instructions for [**macOS**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-macos.md).
|
||||||
|
|
||||||
> [!IMPORTANT]
|
> [!IMPORTANT]
|
||||||
> macOS users need at least macOS 15.4 to run shadPS4. Due to GPU issues there are currently heavy bugs on Intel Macs.
|
> macOS users need at least macOS 15 on Apple Silicon-based Mac devices and at least macOS 14 on Intel-based Mac devices.
|
||||||
|
|
||||||
# Debugging and reporting issues
|
# Debugging and reporting issues
|
||||||
|
|
||||||
|
@ -122,37 +122,19 @@ R3 | M |
|
||||||
Keyboard and mouse inputs can be customized in the settings menu by clicking the Controller button, and further details and help on controls are also found there. Custom bindings are saved per-game. Inputs support up to three keys per binding, mouse buttons, mouse movement mapped to joystick input, and more.
|
Keyboard and mouse inputs can be customized in the settings menu by clicking the Controller button, and further details and help on controls are also found there. Custom bindings are saved per-game. Inputs support up to three keys per binding, mouse buttons, mouse movement mapped to joystick input, and more.
|
||||||
|
|
||||||
|
|
||||||
# Firmware files
|
|
||||||
|
|
||||||
shadPS4 can load some PlayStation 4 firmware files, these must be dumped from your legally owned PlayStation 4 console.\
|
|
||||||
The following firmware modules are supported and must be placed in shadPS4's `user/sys_modules` folder.
|
|
||||||
|
|
||||||
<div align="center">
|
|
||||||
|
|
||||||
| Modules | Modules | Modules | Modules |
|
|
||||||
|-------------------------|-------------------------|-------------------------|-------------------------|
|
|
||||||
| libSceCesCs.sprx | libSceFont.sprx | libSceFontFt.sprx | libSceFreeTypeOt.sprx |
|
|
||||||
| libSceJson.sprx | libSceJson2.sprx | libSceLibcInternal.sprx | libSceNgs2.sprx |
|
|
||||||
| libSceRtc.sprx | libSceUlt.sprx | | |
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
> [!Caution]
|
|
||||||
> The above modules are required to run the games properly and must be extracted from your PlayStation 4.\
|
|
||||||
> **We do not provide any information or support on how to do this**.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Main team
|
# Main team
|
||||||
|
|
||||||
- [**georgemoralis**](https://github.com/georgemoralis)
|
- [**georgemoralis**](https://github.com/georgemoralis)
|
||||||
|
- [**raphaelthegreat**](https://github.com/raphaelthegreat)
|
||||||
- [**psucien**](https://github.com/psucien)
|
- [**psucien**](https://github.com/psucien)
|
||||||
|
- [**skmp**](https://github.com/skmp)
|
||||||
|
- [**wheremyfoodat**](https://github.com/wheremyfoodat)
|
||||||
|
- [**raziel1000**](https://github.com/raziel1000)
|
||||||
- [**viniciuslrangel**](https://github.com/viniciuslrangel)
|
- [**viniciuslrangel**](https://github.com/viniciuslrangel)
|
||||||
- [**roamic**](https://github.com/vladmikhalin)
|
- [**roamic**](https://github.com/vladmikhalin)
|
||||||
|
- [**poly**](https://github.com/polybiusproxy)
|
||||||
- [**squidbus**](https://github.com/squidbus)
|
- [**squidbus**](https://github.com/squidbus)
|
||||||
- [**frodo**](https://github.com/baggins183)
|
- [**frodo**](https://github.com/baggins183)
|
||||||
- [**Stephen Miller**](https://github.com/StevenMiller123)
|
|
||||||
- [**kalaposfos13**](https://github.com/kalaposfos13)
|
|
||||||
|
|
||||||
Logo is done by [**Xphalnos**](https://github.com/Xphalnos)
|
Logo is done by [**Xphalnos**](https://github.com/Xphalnos)
|
||||||
|
|
||||||
|
@ -163,11 +145,11 @@ Open a PR and we'll check it :)
|
||||||
|
|
||||||
# Translations
|
# Translations
|
||||||
|
|
||||||
If you want to translate shadPS4 to your language we use [**Crowdin**](https://crowdin.com/project/shadps4-emulator).
|
If you want to translate shadPS4 to your language we use [**crowdin**](https://crowdin.com/project/shadps4-emulator).
|
||||||
# Contributors
|
# Contributors
|
||||||
|
|
||||||
<a href="https://github.com/shadps4-emu/shadPS4/graphs/contributors">
|
<a href="https://github.com/shadps4-emu/shadPS4/graphs/contributors">
|
||||||
<img src="https://contrib.rocks/image?repo=shadps4-emu/shadPS4&max=24">
|
<img src="https://contrib.rocks/image?repo=shadps4-emu/shadPS4&max=15">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
12
REUSE.toml
12
REUSE.toml
|
@ -30,7 +30,6 @@ path = [
|
||||||
"src/images/dump_icon.png",
|
"src/images/dump_icon.png",
|
||||||
"src/images/exit_icon.png",
|
"src/images/exit_icon.png",
|
||||||
"src/images/file_icon.png",
|
"src/images/file_icon.png",
|
||||||
"src/images/trophy_icon.png",
|
|
||||||
"src/images/flag_china.png",
|
"src/images/flag_china.png",
|
||||||
"src/images/flag_eu.png",
|
"src/images/flag_eu.png",
|
||||||
"src/images/flag_jp.png",
|
"src/images/flag_jp.png",
|
||||||
|
@ -49,26 +48,17 @@ path = [
|
||||||
"src/images/pause_icon.png",
|
"src/images/pause_icon.png",
|
||||||
"src/images/play_icon.png",
|
"src/images/play_icon.png",
|
||||||
"src/images/ps4_controller.png",
|
"src/images/ps4_controller.png",
|
||||||
"src/images/restart_game_icon.png",
|
"src/images/refresh_icon.png",
|
||||||
"src/images/refreshlist_icon.png",
|
|
||||||
"src/images/settings_icon.png",
|
"src/images/settings_icon.png",
|
||||||
"src/images/fullscreen_icon.png",
|
|
||||||
"src/images/stop_icon.png",
|
"src/images/stop_icon.png",
|
||||||
"src/images/utils_icon.png",
|
"src/images/utils_icon.png",
|
||||||
"src/images/shadPS4.icns",
|
"src/images/shadPS4.icns",
|
||||||
"src/images/shadps4.ico",
|
"src/images/shadps4.ico",
|
||||||
"src/images/shadps4.png",
|
|
||||||
"src/images/net.shadps4.shadPS4.svg",
|
"src/images/net.shadps4.shadPS4.svg",
|
||||||
"src/images/themes_icon.png",
|
"src/images/themes_icon.png",
|
||||||
"src/images/update_icon.png",
|
"src/images/update_icon.png",
|
||||||
"src/images/youtube.png",
|
"src/images/youtube.png",
|
||||||
"src/images/website.png",
|
"src/images/website.png",
|
||||||
"src/images/discord.svg",
|
|
||||||
"src/images/github.svg",
|
|
||||||
"src/images/ko-fi.svg",
|
|
||||||
"src/images/shadps4.svg",
|
|
||||||
"src/images/website.svg",
|
|
||||||
"src/images/youtube.svg",
|
|
||||||
"src/shadps4.qrc",
|
"src/shadps4.qrc",
|
||||||
"src/shadps4.rc",
|
"src/shadps4.rc",
|
||||||
"src/qt_gui/translations/update_translation.sh",
|
"src/qt_gui/translations/update_translation.sh",
|
||||||
|
|
15
cmake/Findcryptopp.cmake
Normal file
15
cmake/Findcryptopp.cmake
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
pkg_search_module(CRYPTOPP QUIET IMPORTED_TARGET libcryptopp)
|
||||||
|
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(cryptopp
|
||||||
|
REQUIRED_VARS CRYPTOPP_LINK_LIBRARIES
|
||||||
|
VERSION_VAR CRYPTOPP_VERSION
|
||||||
|
)
|
||||||
|
|
||||||
|
if (cryptopp_FOUND AND NOT TARGET cryptopp::cryptopp)
|
||||||
|
add_library(cryptopp::cryptopp ALIAS PkgConfig::CRYPTOPP)
|
||||||
|
endif()
|
|
@ -1,15 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
find_package(PkgConfig QUIET)
|
|
||||||
pkg_search_module(LIBUSB QUIET IMPORTED_TARGET libusb-1.0)
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
|
||||||
find_package_handle_standard_args(libusb
|
|
||||||
REQUIRED_VARS LIBUSB_LINK_LIBRARIES
|
|
||||||
VERSION_VAR LIBUSB_VERSION
|
|
||||||
)
|
|
||||||
|
|
||||||
if (libusb_FOUND AND NOT TARGET libusb::usb)
|
|
||||||
add_library(libusb::usb ALIAS PkgConfig::LIBUSB)
|
|
||||||
endif()
|
|
3
dist/net.shadps4.shadPS4.metainfo.xml
vendored
3
dist/net.shadps4.shadPS4.metainfo.xml
vendored
|
@ -37,9 +37,6 @@
|
||||||
<category translate="no">Game</category>
|
<category translate="no">Game</category>
|
||||||
</categories>
|
</categories>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="0.8.0" date="2025-05-23">
|
|
||||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.8.0</url>
|
|
||||||
</release>
|
|
||||||
<release version="0.7.0" date="2025-03-23">
|
<release version="0.7.0" date="2025-03-23">
|
||||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.7.0</url>
|
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.7.0</url>
|
||||||
</release>
|
</release>
|
||||||
|
|
BIN
documents/Quickstart/2.png
Normal file
BIN
documents/Quickstart/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 658 KiB |
|
@ -13,6 +13,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
- [**RAM**](#ram)
|
- [**RAM**](#ram)
|
||||||
- [**OS**](#os)
|
- [**OS**](#os)
|
||||||
- [**Have the latest WIP version**](#how-to-run-the-latest-work-in-progress-builds-of-shadps4)
|
- [**Have the latest WIP version**](#how-to-run-the-latest-work-in-progress-builds-of-shadps4)
|
||||||
|
- [**Install PKG files (Games and Updates)**](#install-pkg-files)
|
||||||
- [**Configure the emulator**](#configure-the-emulator)
|
- [**Configure the emulator**](#configure-the-emulator)
|
||||||
|
|
||||||
## Minimum PC requirements
|
## Minimum PC requirements
|
||||||
|
@ -24,13 +25,13 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
- A CPU supporting the following instruction sets: MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, F16C, CLMUL, AES, BMI1, MOVBE, XSAVE, ABM
|
- A CPU supporting the following instruction sets: MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, F16C, CLMUL, AES, BMI1, MOVBE, XSAVE, ABM
|
||||||
- **Intel**: Haswell generation or newer
|
- **Intel**: Haswell generation or newer
|
||||||
- **AMD**: Jaguar generation or newer
|
- **AMD**: Jaguar generation or newer
|
||||||
- **Apple**: Rosetta 2 on macOS 15.4 or newer
|
- **Apple**: Rosetta 2 on macOS 15 or newer
|
||||||
|
|
||||||
### GPU
|
### GPU
|
||||||
|
|
||||||
- A graphics card with at least 1GB of VRAM
|
- A graphics card with at least 1GB of VRAM
|
||||||
- Up-to-date graphics drivers
|
- Keep your graphics drivers up to date
|
||||||
- Vulkan 1.3 with the `VK_KHR_swapchain` and `VK_KHR_push_descriptor` extensions
|
- Vulkan 1.3 support (required)
|
||||||
|
|
||||||
### RAM
|
### RAM
|
||||||
|
|
||||||
|
@ -47,7 +48,13 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
2. Once downloaded, extract to its own folder, and run shadPS4's executable from the extracted folder.
|
2. Once downloaded, extract to its own folder, and run shadPS4's executable from the extracted folder.
|
||||||
|
|
||||||
3. Upon first launch, shadPS4 will prompt you to select a folder to store your installed games in. Select "Browse" and then select a folder that contains your dumped games.
|
3. Upon first launch, shadPS4 will prompt you to select a folder to store your installed games in. Select "Browse" and then select a folder that shadPS4 can use to install your PKG files to.
|
||||||
|
|
||||||
|
## Install PKG files
|
||||||
|
|
||||||
|
To install PKG files (game and updates), you will need the Qt application (with UI). You will have to go to "File" then to "Install Packages (PKG)", a window will open then you will have to select the files. You can install multiple PKG files at once. Once finished, the game should appear in the application.
|
||||||
|
|
||||||
|
<img src="https://github.com/shadps4-emu/shadPS4/blob/main/documents/Quickstart/2.png" width="800">
|
||||||
|
|
||||||
## Configure the emulator
|
## Configure the emulator
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ Now run the emulator. If Qt was enabled at configure time:
|
||||||
./build/shadps4
|
./build/shadps4
|
||||||
```
|
```
|
||||||
|
|
||||||
Otherwise, specify the path to your game's boot file:
|
Otherwise, specify the path to your PKG's boot file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./build/shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
|
./build/shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
|
||||||
|
|
22
externals/CMakeLists.txt
vendored
22
externals/CMakeLists.txt
vendored
|
@ -26,7 +26,21 @@ if (NOT TARGET fmt::fmt)
|
||||||
add_subdirectory(fmt)
|
add_subdirectory(fmt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# FFmpeg
|
# CryptoPP
|
||||||
|
if (NOT TARGET cryptopp::cryptopp)
|
||||||
|
set(CRYPTOPP_INSTALL OFF)
|
||||||
|
set(CRYPTOPP_BUILD_TESTING OFF)
|
||||||
|
set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp)
|
||||||
|
# cryptopp instruction set checks do not account for added compile options,
|
||||||
|
# so disable extensions in the library config to match our chosen target CPU.
|
||||||
|
set(CRYPTOPP_DISABLE_AESNI ON)
|
||||||
|
set(CRYPTOPP_DISABLE_AVX2 ON)
|
||||||
|
add_subdirectory(cryptopp-cmake)
|
||||||
|
file(COPY cryptopp DESTINATION cryptopp FILES_MATCHING PATTERN "*.h")
|
||||||
|
# remove externals/cryptopp from include directories because it contains a conflicting zlib.h file
|
||||||
|
set_target_properties(cryptopp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/cryptopp")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT TARGET FFmpeg::ffmpeg)
|
if (NOT TARGET FFmpeg::ffmpeg)
|
||||||
add_subdirectory(ffmpeg-core)
|
add_subdirectory(ffmpeg-core)
|
||||||
add_library(FFmpeg::ffmpeg ALIAS ffmpeg)
|
add_library(FFmpeg::ffmpeg ALIAS ffmpeg)
|
||||||
|
@ -201,12 +215,6 @@ if (NOT TARGET pugixml::pugixml)
|
||||||
add_subdirectory(pugixml)
|
add_subdirectory(pugixml)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# libusb
|
|
||||||
if (NOT TARGET libusb::usb)
|
|
||||||
add_subdirectory(libusb)
|
|
||||||
add_library(libusb::usb ALIAS usb-1.0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Discord RPC
|
# Discord RPC
|
||||||
if (ENABLE_DISCORD_RPC)
|
if (ENABLE_DISCORD_RPC)
|
||||||
add_subdirectory(discord-rpc)
|
add_subdirectory(discord-rpc)
|
||||||
|
|
2
externals/MoltenVK/MoltenVK
vendored
2
externals/MoltenVK/MoltenVK
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 87a8e8b13d4ad8835367fea1ebad1896d0460946
|
Subproject commit 2048427e50f9eb20f2b8f98d316ecaee398c9b91
|
8
externals/MoltenVK/MoltenVK_icd.json
vendored
Normal file
8
externals/MoltenVK/MoltenVK_icd.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"file_format_version": "1.0.0",
|
||||||
|
"ICD": {
|
||||||
|
"library_path": "../../../Frameworks/libMoltenVK.dylib",
|
||||||
|
"api_version": "1.2.0",
|
||||||
|
"is_portability_driver": true
|
||||||
|
}
|
||||||
|
}
|
2
externals/MoltenVK/SPIRV-Cross
vendored
2
externals/MoltenVK/SPIRV-Cross
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 7918775748c5e2f5c40d9918ce68825035b5a1e1
|
Subproject commit 2c32b6bf86f3c4a5539aa1f0bacbd59fe61759cf
|
2
externals/MoltenVK/cereal
vendored
2
externals/MoltenVK/cereal
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a56bad8bbb770ee266e930c95d37fff2a5be7fea
|
Subproject commit d1fcec807b372f04e4c1041b3058e11c12853e6e
|
1
externals/cryptopp
vendored
Submodule
1
externals/cryptopp
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit effed0d0b865afc23ed67e0916f83734e4b9b3b7
|
1
externals/cryptopp-cmake
vendored
Submodule
1
externals/cryptopp-cmake
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 2c384c28265a93358a2455e610e76393358794df
|
2
externals/date
vendored
2
externals/date
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a45ea7c17b4a7f320e199b71436074bd624c9e15
|
Subproject commit 28b7b232521ace2c8ef3f2ad4126daec3569c14f
|
2
externals/dear_imgui
vendored
2
externals/dear_imgui
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit f4d9359095eff3eb03f685921edc1cf0e37b1687
|
Subproject commit 636cd4a7d623a2bc9bf59bb3acbb4ca075befba3
|
2
externals/discord-rpc
vendored
2
externals/discord-rpc
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 19f66e6dcabb2268965f453db9e5774ede43238f
|
Subproject commit 51b09d426a4a1bcfa6ee6d4894e57d669f4a2e65
|
2
externals/ffmpeg-core
vendored
2
externals/ffmpeg-core
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit b0de1dcca26c0ebfb8011b8e59dd17fc399db0ff
|
Subproject commit 27de97c826b6b40c255891c37ac046a25836a575
|
2
externals/fmt
vendored
2
externals/fmt
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 64db979e38ec644b1798e41610b28c8d2c8a2739
|
Subproject commit 8ee89546ffcf046309d1f0d38c0393f02fde56c8
|
2
externals/glslang
vendored
2
externals/glslang
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit ba1640446f3826a518721d1f083f3a8cca1120c3
|
Subproject commit a0995c49ebcaca2c6d3b03efbabf74f3843decdb
|
1
externals/libusb
vendored
1
externals/libusb
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit a63a7e43e0950a595cf4b98a0eaf4051749ace5f
|
|
2
externals/magic_enum
vendored
2
externals/magic_enum
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a413fcc9c46a020a746907136a384c227f3cd095
|
Subproject commit 1a1824df7ac798177a521eed952720681b0bf482
|
2
externals/pugixml
vendored
2
externals/pugixml
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit caade5a28aad86b92a4b5337a9dc70c4ba73c5eb
|
Subproject commit 4bc14418d12d289dd9978fdce9490a45deeb653e
|
2
externals/robin-map
vendored
2
externals/robin-map
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 4ec1bf19c6a96125ea22062f38c2cf5b958e448e
|
Subproject commit fe845fd7852ef541c5479ae23b3d36b57f8608ee
|
2
externals/sdl3
vendored
2
externals/sdl3
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 4093e4a193971ef1d4928158e0a1832be42e4599
|
Subproject commit a336b62d8b0b97b09214e053203e442e2b6e2be5
|
2
externals/sirit
vendored
2
externals/sirit
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 09a1416ab1b59ddfebd2618412f118f2004f3b2c
|
Subproject commit 8b9b12c2089505ac8b10fa56bf56b3ed49d9d7b0
|
2
externals/toml11
vendored
2
externals/toml11
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a01fe3b4c14c6d7b99ee3f07c9e80058c6403097
|
Subproject commit 7f6c574ff5aa1053534e7e19c0a4f22bf4c6aaca
|
2
externals/vma
vendored
2
externals/vma
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit f378e7b3f18f6e2b06b957f6ba7b1c7207d2a536
|
Subproject commit 5a53a198945ba8260fbc58fadb788745ce6aa263
|
2
externals/vulkan-headers
vendored
2
externals/vulkan-headers
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 5ceb9ed481e58e705d0d9b5326537daedd06b97d
|
Subproject commit a03d2f6d5753b365d704d58161825890baad0755
|
2
externals/winpthreads
vendored
2
externals/winpthreads
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit f35b0948d36a736e6a2d052ae295a3ffde09703f
|
Subproject commit f00c973a6ab2a23573708568b8ef4acc20a9d36b
|
2
externals/xbyak
vendored
2
externals/xbyak
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 44a72f369268f7d552650891b296693e91db86bb
|
Subproject commit 4e44f4614ddbf038f2a6296f5b906d5c72691e0f
|
2
externals/xxhash
vendored
2
externals/xxhash
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 953a09abc39096da9e216b6eb0002c681cdc1199
|
Subproject commit 2bf8313b934633b2a5b7e8fd239645b85e10c852
|
2
externals/zlib-ng
vendored
2
externals/zlib-ng
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit fd0d263cedab1a136f40d65199987e3eaeecfcbd
|
Subproject commit d54e3769be0c522015b784eca2af258b1c026107
|
2
externals/zydis
vendored
2
externals/zydis
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 120e0e705f8e3b507dc49377ac2879979f0d545c
|
Subproject commit bffbb610cfea643b98e87658b9058382f7522807
|
1195
src/common/aes.h
1195
src/common/aes.h
File diff suppressed because it is too large
Load diff
|
@ -7,10 +7,10 @@
|
||||||
#include <fmt/xchar.h> // for wstring support
|
#include <fmt/xchar.h> // for wstring support
|
||||||
#include <toml.hpp>
|
#include <toml.hpp>
|
||||||
|
|
||||||
#include "common/config.h"
|
|
||||||
#include "common/logging/formatter.h"
|
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "common/scm_rev.h"
|
#include "config.h"
|
||||||
|
#include "logging/formatter.h"
|
||||||
|
#include "version.h"
|
||||||
|
|
||||||
namespace toml {
|
namespace toml {
|
||||||
template <typename TC, typename K>
|
template <typename TC, typename K>
|
||||||
|
@ -32,7 +32,6 @@ std::filesystem::path find_fs_path_or(const basic_value<TC>& v, const K& ky,
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
|
||||||
static bool isNeo = false;
|
static bool isNeo = false;
|
||||||
static bool isDevKit = false;
|
|
||||||
static bool playBGM = false;
|
static bool playBGM = false;
|
||||||
static bool isTrophyPopupDisabled = false;
|
static bool isTrophyPopupDisabled = false;
|
||||||
static int BGMvolume = 50;
|
static int BGMvolume = 50;
|
||||||
|
@ -41,7 +40,7 @@ static u32 screenWidth = 1280;
|
||||||
static u32 screenHeight = 720;
|
static u32 screenHeight = 720;
|
||||||
static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto select
|
static s32 gpuId = -1; // Vulkan physical device index. Set to negative for auto select
|
||||||
static std::string logFilter;
|
static std::string logFilter;
|
||||||
static std::string logType = "sync";
|
static std::string logType = "async";
|
||||||
static std::string userName = "shadPS4";
|
static std::string userName = "shadPS4";
|
||||||
static std::string updateChannel;
|
static std::string updateChannel;
|
||||||
static std::string chooseHomeTab;
|
static std::string chooseHomeTab;
|
||||||
|
@ -75,14 +74,14 @@ static double trophyNotificationDuration = 6.0;
|
||||||
static bool useUnifiedInputConfig = true;
|
static bool useUnifiedInputConfig = true;
|
||||||
static bool overrideControllerColor = false;
|
static bool overrideControllerColor = false;
|
||||||
static int controllerCustomColorRGB[3] = {0, 0, 255};
|
static int controllerCustomColorRGB[3] = {0, 0, 255};
|
||||||
|
static bool separateupdatefolder = false;
|
||||||
static bool compatibilityData = false;
|
static bool compatibilityData = false;
|
||||||
static bool checkCompatibilityOnStartup = false;
|
static bool checkCompatibilityOnStartup = false;
|
||||||
static std::string trophyKey;
|
static std::string trophyKey;
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
static bool load_game_size = true;
|
static bool load_game_size = true;
|
||||||
static std::vector<GameInstallDir> settings_install_dirs = {};
|
std::vector<std::filesystem::path> settings_install_dirs = {};
|
||||||
std::vector<bool> install_dirs_enabled = {};
|
|
||||||
std::filesystem::path settings_addon_install_dir = {};
|
std::filesystem::path settings_addon_install_dir = {};
|
||||||
std::filesystem::path save_data_path = {};
|
std::filesystem::path save_data_path = {};
|
||||||
u32 main_window_geometry_x = 400;
|
u32 main_window_geometry_x = 400;
|
||||||
|
@ -97,6 +96,7 @@ u32 m_slider_pos_grid = 0;
|
||||||
u32 m_table_mode = 0;
|
u32 m_table_mode = 0;
|
||||||
u32 m_window_size_W = 1280;
|
u32 m_window_size_W = 1280;
|
||||||
u32 m_window_size_H = 720;
|
u32 m_window_size_H = 720;
|
||||||
|
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_US";
|
std::string emulator_language = "en_US";
|
||||||
|
@ -105,7 +105,6 @@ static bool showBackgroundImage = true;
|
||||||
static bool isFullscreen = false;
|
static bool isFullscreen = false;
|
||||||
static std::string fullscreenMode = "Windowed";
|
static std::string fullscreenMode = "Windowed";
|
||||||
static bool isHDRAllowed = false;
|
static bool isHDRAllowed = false;
|
||||||
static bool showLabelsUnderIcons = true;
|
|
||||||
|
|
||||||
// Language
|
// Language
|
||||||
u32 m_language = 1; // english
|
u32 m_language = 1; // english
|
||||||
|
@ -167,22 +166,10 @@ bool isNeoModeConsole() {
|
||||||
return isNeo;
|
return isNeo;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDevKitConsole() {
|
|
||||||
return isDevKit;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getIsFullscreen() {
|
bool getIsFullscreen() {
|
||||||
return isFullscreen;
|
return isFullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getShowLabelsUnderIcons() {
|
|
||||||
return showLabelsUnderIcons;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setShowLabelsUnderIcons() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string getFullscreenMode() {
|
std::string getFullscreenMode() {
|
||||||
return fullscreenMode;
|
return fullscreenMode;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +338,10 @@ void setVkGuestMarkersEnabled(bool enable) {
|
||||||
vkGuestMarkers = enable;
|
vkGuestMarkers = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getSeparateUpdateEnabled() {
|
||||||
|
return separateupdatefolder;
|
||||||
|
}
|
||||||
|
|
||||||
bool getCompatibilityEnabled() {
|
bool getCompatibilityEnabled() {
|
||||||
return compatibilityData;
|
return compatibilityData;
|
||||||
}
|
}
|
||||||
|
@ -430,9 +421,6 @@ void setVblankDiv(u32 value) {
|
||||||
void setIsFullscreen(bool enable) {
|
void setIsFullscreen(bool enable) {
|
||||||
isFullscreen = enable;
|
isFullscreen = enable;
|
||||||
}
|
}
|
||||||
static void setShowLabelsUnderIcons(bool enable) {
|
|
||||||
showLabelsUnderIcons = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFullscreenMode(std::string mode) {
|
void setFullscreenMode(std::string mode) {
|
||||||
fullscreenMode = mode;
|
fullscreenMode = mode;
|
||||||
|
@ -512,6 +500,10 @@ void setIsMotionControlsEnabled(bool use) {
|
||||||
isMotionControlsEnabled = use;
|
isMotionControlsEnabled = use;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setSeparateUpdateEnabled(bool use) {
|
||||||
|
separateupdatefolder = use;
|
||||||
|
}
|
||||||
|
|
||||||
void setCompatibilityEnabled(bool use) {
|
void setCompatibilityEnabled(bool use) {
|
||||||
compatibilityData = use;
|
compatibilityData = use;
|
||||||
}
|
}
|
||||||
|
@ -527,34 +519,22 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
||||||
main_window_geometry_h = h;
|
main_window_geometry_h = h;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addGameInstallDir(const std::filesystem::path& dir, bool enabled) {
|
bool addGameInstallDir(const std::filesystem::path& dir) {
|
||||||
for (const auto& install_dir : settings_install_dirs) {
|
if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) ==
|
||||||
if (install_dir.path == dir) {
|
settings_install_dirs.end()) {
|
||||||
return false;
|
settings_install_dirs.push_back(dir);
|
||||||
}
|
|
||||||
}
|
|
||||||
settings_install_dirs.push_back({dir, enabled});
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void removeGameInstallDir(const std::filesystem::path& dir) {
|
void removeGameInstallDir(const std::filesystem::path& dir) {
|
||||||
auto iterator =
|
auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir);
|
||||||
std::find_if(settings_install_dirs.begin(), settings_install_dirs.end(),
|
|
||||||
[&dir](const GameInstallDir& install_dir) { return install_dir.path == dir; });
|
|
||||||
if (iterator != settings_install_dirs.end()) {
|
if (iterator != settings_install_dirs.end()) {
|
||||||
settings_install_dirs.erase(iterator);
|
settings_install_dirs.erase(iterator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGameInstallDirEnabled(const std::filesystem::path& dir, bool enabled) {
|
|
||||||
auto iterator =
|
|
||||||
std::find_if(settings_install_dirs.begin(), settings_install_dirs.end(),
|
|
||||||
[&dir](const GameInstallDir& install_dir) { return install_dir.path == dir; });
|
|
||||||
if (iterator != settings_install_dirs.end()) {
|
|
||||||
iterator->enabled = enabled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir) {
|
void setAddonInstallDir(const std::filesystem::path& dir) {
|
||||||
settings_addon_install_dir = dir;
|
settings_addon_install_dir = dir;
|
||||||
}
|
}
|
||||||
|
@ -591,6 +571,11 @@ void setMainWindowHeight(u32 height) {
|
||||||
m_window_size_H = height;
|
m_window_size_H = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setPkgViewer(const std::vector<std::string>& pkgList) {
|
||||||
|
m_pkg_viewer.resize(pkgList.size());
|
||||||
|
m_pkg_viewer = pkgList;
|
||||||
|
}
|
||||||
|
|
||||||
void setElfViewer(const std::vector<std::string>& elfList) {
|
void setElfViewer(const std::vector<std::string>& elfList) {
|
||||||
m_elf_viewer.resize(elfList.size());
|
m_elf_viewer.resize(elfList.size());
|
||||||
m_elf_viewer = elfList;
|
m_elf_viewer = elfList;
|
||||||
|
@ -605,15 +590,8 @@ void setEmulatorLanguage(std::string language) {
|
||||||
emulator_language = language;
|
emulator_language = language;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setGameInstallDirs(const std::vector<std::filesystem::path>& dirs_config) {
|
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config) {
|
||||||
settings_install_dirs.clear();
|
settings_install_dirs = settings_install_dirs_config;
|
||||||
for (const auto& dir : dirs_config) {
|
|
||||||
settings_install_dirs.push_back({dir, true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setAllGameInstallDirs(const std::vector<GameInstallDir>& dirs_config) {
|
|
||||||
settings_install_dirs = dirs_config;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSaveDataPath(const std::filesystem::path& path) {
|
void setSaveDataPath(const std::filesystem::path& path) {
|
||||||
|
@ -636,22 +614,8 @@ u32 getMainWindowGeometryH() {
|
||||||
return main_window_geometry_h;
|
return main_window_geometry_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::filesystem::path> getGameInstallDirs() {
|
const std::vector<std::filesystem::path>& getGameInstallDirs() {
|
||||||
std::vector<std::filesystem::path> enabled_dirs;
|
return settings_install_dirs;
|
||||||
for (const auto& dir : settings_install_dirs) {
|
|
||||||
if (dir.enabled) {
|
|
||||||
enabled_dirs.push_back(dir.path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return enabled_dirs;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::vector<bool> getGameInstallDirsEnabled() {
|
|
||||||
std::vector<bool> enabled_dirs;
|
|
||||||
for (const auto& dir : settings_install_dirs) {
|
|
||||||
enabled_dirs.push_back(dir.enabled);
|
|
||||||
}
|
|
||||||
return enabled_dirs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path getAddonInstallDir() {
|
std::filesystem::path getAddonInstallDir() {
|
||||||
|
@ -694,6 +658,10 @@ u32 getMainWindowHeight() {
|
||||||
return m_window_size_H;
|
return m_window_size_H;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> getPkgViewer() {
|
||||||
|
return m_pkg_viewer;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> getElfViewer() {
|
std::vector<std::string> getElfViewer() {
|
||||||
return m_elf_viewer;
|
return m_elf_viewer;
|
||||||
}
|
}
|
||||||
|
@ -753,7 +721,6 @@ void load(const std::filesystem::path& path) {
|
||||||
const toml::value& general = data.at("General");
|
const toml::value& general = data.at("General");
|
||||||
|
|
||||||
isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
|
isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
|
||||||
isDevKit = toml::find_or<bool>(general, "isDevKit", false);
|
|
||||||
playBGM = toml::find_or<bool>(general, "playBGM", false);
|
playBGM = toml::find_or<bool>(general, "playBGM", false);
|
||||||
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
|
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
|
||||||
trophyNotificationDuration =
|
trophyNotificationDuration =
|
||||||
|
@ -763,7 +730,7 @@ void load(const std::filesystem::path& path) {
|
||||||
logFilter = toml::find_or<std::string>(general, "logFilter", "");
|
logFilter = toml::find_or<std::string>(general, "logFilter", "");
|
||||||
logType = toml::find_or<std::string>(general, "logType", "sync");
|
logType = toml::find_or<std::string>(general, "logType", "sync");
|
||||||
userName = toml::find_or<std::string>(general, "userName", "shadPS4");
|
userName = toml::find_or<std::string>(general, "userName", "shadPS4");
|
||||||
if (Common::g_is_release) {
|
if (Common::isRelease) {
|
||||||
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Release");
|
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Release");
|
||||||
} else {
|
} else {
|
||||||
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Nightly");
|
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Nightly");
|
||||||
|
@ -772,6 +739,7 @@ void load(const std::filesystem::path& path) {
|
||||||
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
||||||
isAlwaysShowChangelog = toml::find_or<bool>(general, "alwaysShowChangelog", false);
|
isAlwaysShowChangelog = toml::find_or<bool>(general, "alwaysShowChangelog", false);
|
||||||
isSideTrophy = toml::find_or<std::string>(general, "sideTrophy", "right");
|
isSideTrophy = toml::find_or<std::string>(general, "sideTrophy", "right");
|
||||||
|
separateupdatefolder = toml::find_or<bool>(general, "separateUpdateEnabled", false);
|
||||||
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
|
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
|
||||||
checkCompatibilityOnStartup =
|
checkCompatibilityOnStartup =
|
||||||
toml::find_or<bool>(general, "checkCompatibilityOnStartup", false);
|
toml::find_or<bool>(general, "checkCompatibilityOnStartup", false);
|
||||||
|
@ -840,23 +808,9 @@ void load(const std::filesystem::path& path) {
|
||||||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||||
|
|
||||||
const auto install_dir_array =
|
const auto install_dir_array =
|
||||||
toml::find_or<std::vector<std::u8string>>(gui, "installDirs", {});
|
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||||
|
for (const auto& dir : install_dir_array) {
|
||||||
try {
|
addGameInstallDir(std::filesystem::path{dir});
|
||||||
install_dirs_enabled = toml::find<std::vector<bool>>(gui, "installDirsEnabled");
|
|
||||||
} catch (...) {
|
|
||||||
// If it does not exist, assume that all are enabled.
|
|
||||||
install_dirs_enabled.resize(install_dir_array.size(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (install_dirs_enabled.size() < install_dir_array.size()) {
|
|
||||||
install_dirs_enabled.resize(install_dir_array.size(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
settings_install_dirs.clear();
|
|
||||||
for (size_t i = 0; i < install_dir_array.size(); i++) {
|
|
||||||
settings_install_dirs.push_back(
|
|
||||||
{std::filesystem::path{install_dir_array[i]}, install_dirs_enabled[i]});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
|
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
|
||||||
|
@ -866,6 +820,7 @@ void load(const std::filesystem::path& path) {
|
||||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||||
main_window_geometry_w = toml::find_or<int>(gui, "geometry_w", 0);
|
main_window_geometry_w = toml::find_or<int>(gui, "geometry_w", 0);
|
||||||
main_window_geometry_h = toml::find_or<int>(gui, "geometry_h", 0);
|
main_window_geometry_h = toml::find_or<int>(gui, "geometry_h", 0);
|
||||||
|
m_pkg_viewer = toml::find_or<std::vector<std::string>>(gui, "pkgDirs", {});
|
||||||
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);
|
||||||
|
@ -898,37 +853,6 @@ void load(const std::filesystem::path& path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sortTomlSections(toml::ordered_value& data) {
|
|
||||||
toml::ordered_value ordered_data;
|
|
||||||
std::vector<std::string> section_order = {"General", "Input", "GPU", "Vulkan",
|
|
||||||
"Debug", "Keys", "GUI", "Settings"};
|
|
||||||
|
|
||||||
for (const auto& section : section_order) {
|
|
||||||
if (data.contains(section)) {
|
|
||||||
std::vector<std::string> keys;
|
|
||||||
for (const auto& item : data.at(section).as_table()) {
|
|
||||||
keys.push_back(item.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::sort(keys.begin(), keys.end(), [](const std::string& a, const std::string& b) {
|
|
||||||
return std::lexicographical_compare(
|
|
||||||
a.begin(), a.end(), b.begin(), b.end(), [](char a_char, char b_char) {
|
|
||||||
return std::tolower(a_char) < std::tolower(b_char);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
toml::ordered_value ordered_section;
|
|
||||||
for (const auto& key : keys) {
|
|
||||||
ordered_section[key] = data.at(section).at(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
ordered_data[section] = ordered_section;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
data = ordered_data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void save(const std::filesystem::path& path) {
|
void save(const std::filesystem::path& path) {
|
||||||
toml::ordered_value data;
|
toml::ordered_value data;
|
||||||
|
|
||||||
|
@ -952,7 +876,6 @@ void save(const std::filesystem::path& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
data["General"]["isPS4Pro"] = isNeo;
|
data["General"]["isPS4Pro"] = isNeo;
|
||||||
data["General"]["isDevKit"] = isDevKit;
|
|
||||||
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
|
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
|
||||||
data["General"]["trophyNotificationDuration"] = trophyNotificationDuration;
|
data["General"]["trophyNotificationDuration"] = trophyNotificationDuration;
|
||||||
data["General"]["playBGM"] = playBGM;
|
data["General"]["playBGM"] = playBGM;
|
||||||
|
@ -967,6 +890,7 @@ void save(const std::filesystem::path& path) {
|
||||||
data["General"]["autoUpdate"] = isAutoUpdate;
|
data["General"]["autoUpdate"] = isAutoUpdate;
|
||||||
data["General"]["alwaysShowChangelog"] = isAlwaysShowChangelog;
|
data["General"]["alwaysShowChangelog"] = isAlwaysShowChangelog;
|
||||||
data["General"]["sideTrophy"] = isSideTrophy;
|
data["General"]["sideTrophy"] = isSideTrophy;
|
||||||
|
data["General"]["separateUpdateEnabled"] = separateupdatefolder;
|
||||||
data["General"]["compatibilityEnabled"] = compatibilityData;
|
data["General"]["compatibilityEnabled"] = compatibilityData;
|
||||||
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
|
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
|
||||||
data["Input"]["cursorState"] = cursorState;
|
data["Input"]["cursorState"] = cursorState;
|
||||||
|
@ -998,37 +922,14 @@ void save(const std::filesystem::path& path) {
|
||||||
data["Debug"]["CollectShader"] = isShaderDebug;
|
data["Debug"]["CollectShader"] = isShaderDebug;
|
||||||
data["Debug"]["isSeparateLogFilesEnabled"] = isSeparateLogFilesEnabled;
|
data["Debug"]["isSeparateLogFilesEnabled"] = isSeparateLogFilesEnabled;
|
||||||
data["Debug"]["FPSColor"] = isFpsColor;
|
data["Debug"]["FPSColor"] = isFpsColor;
|
||||||
|
|
||||||
data["Keys"]["TrophyKey"] = trophyKey;
|
data["Keys"]["TrophyKey"] = trophyKey;
|
||||||
|
|
||||||
std::vector<std::string> install_dirs;
|
std::vector<std::string> install_dirs;
|
||||||
std::vector<bool> install_dirs_enabled;
|
for (const auto& dirString : settings_install_dirs) {
|
||||||
|
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
||||||
// temporary structure for ordering
|
|
||||||
struct DirEntry {
|
|
||||||
std::string path_str;
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<DirEntry> sorted_dirs;
|
|
||||||
for (const auto& dirInfo : settings_install_dirs) {
|
|
||||||
sorted_dirs.push_back(
|
|
||||||
{std::string{fmt::UTF(dirInfo.path.u8string()).data}, dirInfo.enabled});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort directories alphabetically
|
|
||||||
std::sort(sorted_dirs.begin(), sorted_dirs.end(), [](const DirEntry& a, const DirEntry& b) {
|
|
||||||
return std::lexicographical_compare(
|
|
||||||
a.path_str.begin(), a.path_str.end(), b.path_str.begin(), b.path_str.end(),
|
|
||||||
[](char a_char, char b_char) { return std::tolower(a_char) < std::tolower(b_char); });
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const auto& entry : sorted_dirs) {
|
|
||||||
install_dirs.push_back(entry.path_str);
|
|
||||||
install_dirs_enabled.push_back(entry.enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
data["GUI"]["installDirs"] = install_dirs;
|
data["GUI"]["installDirs"] = install_dirs;
|
||||||
data["GUI"]["installDirsEnabled"] = install_dirs_enabled;
|
|
||||||
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
|
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
|
||||||
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
||||||
|
|
||||||
|
@ -1039,13 +940,9 @@ void save(const std::filesystem::path& path) {
|
||||||
data["GUI"]["showBackgroundImage"] = showBackgroundImage;
|
data["GUI"]["showBackgroundImage"] = showBackgroundImage;
|
||||||
data["Settings"]["consoleLanguage"] = m_language;
|
data["Settings"]["consoleLanguage"] = m_language;
|
||||||
|
|
||||||
// Sorting of TOML sections
|
|
||||||
sortTomlSections(data);
|
|
||||||
|
|
||||||
std::ofstream file(path, std::ios::binary);
|
std::ofstream file(path, std::ios::binary);
|
||||||
file << data;
|
file << data;
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
saveMainWindow(path);
|
saveMainWindow(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1083,12 +980,10 @@ void saveMainWindow(const std::filesystem::path& path) {
|
||||||
data["GUI"]["geometry_y"] = main_window_geometry_y;
|
data["GUI"]["geometry_y"] = main_window_geometry_y;
|
||||||
data["GUI"]["geometry_w"] = main_window_geometry_w;
|
data["GUI"]["geometry_w"] = main_window_geometry_w;
|
||||||
data["GUI"]["geometry_h"] = main_window_geometry_h;
|
data["GUI"]["geometry_h"] = main_window_geometry_h;
|
||||||
|
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;
|
||||||
|
|
||||||
// Sorting of TOML sections
|
|
||||||
sortTomlSections(data);
|
|
||||||
|
|
||||||
std::ofstream file(path, std::ios::binary);
|
std::ofstream file(path, std::ios::binary);
|
||||||
file << data;
|
file << data;
|
||||||
file.close();
|
file.close();
|
||||||
|
@ -1097,7 +992,6 @@ void saveMainWindow(const std::filesystem::path& path) {
|
||||||
void setDefaultValues() {
|
void setDefaultValues() {
|
||||||
isHDRAllowed = false;
|
isHDRAllowed = false;
|
||||||
isNeo = false;
|
isNeo = false;
|
||||||
isDevKit = false;
|
|
||||||
isFullscreen = false;
|
isFullscreen = false;
|
||||||
isTrophyPopupDisabled = false;
|
isTrophyPopupDisabled = false;
|
||||||
playBGM = false;
|
playBGM = false;
|
||||||
|
@ -1106,9 +1000,9 @@ void setDefaultValues() {
|
||||||
screenWidth = 1280;
|
screenWidth = 1280;
|
||||||
screenHeight = 720;
|
screenHeight = 720;
|
||||||
logFilter = "";
|
logFilter = "";
|
||||||
logType = "sync";
|
logType = "async";
|
||||||
userName = "shadPS4";
|
userName = "shadPS4";
|
||||||
if (Common::g_is_release) {
|
if (Common::isRelease) {
|
||||||
updateChannel = "Release";
|
updateChannel = "Release";
|
||||||
} else {
|
} else {
|
||||||
updateChannel = "Nightly";
|
updateChannel = "Nightly";
|
||||||
|
@ -1139,6 +1033,7 @@ void setDefaultValues() {
|
||||||
emulator_language = "en_US";
|
emulator_language = "en_US";
|
||||||
m_language = 1;
|
m_language = 1;
|
||||||
gpuId = -1;
|
gpuId = -1;
|
||||||
|
separateupdatefolder = false;
|
||||||
compatibilityData = false;
|
compatibilityData = false;
|
||||||
checkCompatibilityOnStartup = false;
|
checkCompatibilityOnStartup = false;
|
||||||
backgroundImageOpacity = 50;
|
backgroundImageOpacity = 50;
|
||||||
|
|
|
@ -9,11 +9,6 @@
|
||||||
|
|
||||||
namespace Config {
|
namespace Config {
|
||||||
|
|
||||||
struct GameInstallDir {
|
|
||||||
std::filesystem::path path;
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum HideCursorState : s16 { Never, Idle, Always };
|
enum HideCursorState : s16 { Never, Idle, Always };
|
||||||
|
|
||||||
void load(const std::filesystem::path& path);
|
void load(const std::filesystem::path& path);
|
||||||
|
@ -26,15 +21,13 @@ bool GetLoadGameSizeEnabled();
|
||||||
std::filesystem::path GetSaveDataPath();
|
std::filesystem::path GetSaveDataPath();
|
||||||
void setLoadGameSizeEnabled(bool enable);
|
void setLoadGameSizeEnabled(bool enable);
|
||||||
bool getIsFullscreen();
|
bool getIsFullscreen();
|
||||||
bool getShowLabelsUnderIcons();
|
|
||||||
bool setShowLabelsUnderIcons();
|
|
||||||
std::string getFullscreenMode();
|
std::string getFullscreenMode();
|
||||||
bool isNeoModeConsole();
|
bool isNeoModeConsole();
|
||||||
bool isDevKitConsole();
|
|
||||||
bool getPlayBGM();
|
bool getPlayBGM();
|
||||||
int getBGMvolume();
|
int getBGMvolume();
|
||||||
bool getisTrophyPopupDisabled();
|
bool getisTrophyPopupDisabled();
|
||||||
bool getEnableDiscordRPC();
|
bool getEnableDiscordRPC();
|
||||||
|
bool getSeparateUpdateEnabled();
|
||||||
bool getCompatibilityEnabled();
|
bool getCompatibilityEnabled();
|
||||||
bool getCheckCompatibilityOnStartup();
|
bool getCheckCompatibilityOnStartup();
|
||||||
int getBackgroundImageOpacity();
|
int getBackgroundImageOpacity();
|
||||||
|
@ -104,8 +97,8 @@ void setNeoMode(bool enable);
|
||||||
void setUserName(const std::string& type);
|
void setUserName(const std::string& type);
|
||||||
void setUpdateChannel(const std::string& type);
|
void setUpdateChannel(const std::string& type);
|
||||||
void setChooseHomeTab(const std::string& type);
|
void setChooseHomeTab(const std::string& type);
|
||||||
void setGameInstallDirs(const std::vector<std::filesystem::path>& dirs_config);
|
void setSeparateUpdateEnabled(bool use);
|
||||||
void setAllGameInstallDirs(const std::vector<GameInstallDir>& dirs_config);
|
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
|
||||||
void setSaveDataPath(const std::filesystem::path& path);
|
void setSaveDataPath(const std::filesystem::path& path);
|
||||||
void setCompatibilityEnabled(bool use);
|
void setCompatibilityEnabled(bool use);
|
||||||
void setCheckCompatibilityOnStartup(bool use);
|
void setCheckCompatibilityOnStartup(bool use);
|
||||||
|
@ -140,9 +133,8 @@ void setVkGuestMarkersEnabled(bool enable);
|
||||||
|
|
||||||
// Gui
|
// Gui
|
||||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
||||||
bool addGameInstallDir(const std::filesystem::path& dir, bool enabled = true);
|
bool addGameInstallDir(const std::filesystem::path& dir);
|
||||||
void removeGameInstallDir(const std::filesystem::path& dir);
|
void removeGameInstallDir(const std::filesystem::path& dir);
|
||||||
void setGameInstallDirEnabled(const std::filesystem::path& dir, bool enabled);
|
|
||||||
void setAddonInstallDir(const std::filesystem::path& dir);
|
void setAddonInstallDir(const std::filesystem::path& dir);
|
||||||
void setMainWindowTheme(u32 theme);
|
void setMainWindowTheme(u32 theme);
|
||||||
void setIconSize(u32 size);
|
void setIconSize(u32 size);
|
||||||
|
@ -152,6 +144,7 @@ void setSliderPositionGrid(u32 pos);
|
||||||
void setTableMode(u32 mode);
|
void setTableMode(u32 mode);
|
||||||
void setMainWindowWidth(u32 width);
|
void setMainWindowWidth(u32 width);
|
||||||
void setMainWindowHeight(u32 height);
|
void setMainWindowHeight(u32 height);
|
||||||
|
void setPkgViewer(const std::vector<std::string>& pkgList);
|
||||||
void setElfViewer(const std::vector<std::string>& elfList);
|
void setElfViewer(const std::vector<std::string>& elfList);
|
||||||
void setRecentFiles(const std::vector<std::string>& recentFiles);
|
void setRecentFiles(const std::vector<std::string>& recentFiles);
|
||||||
void setEmulatorLanguage(std::string language);
|
void setEmulatorLanguage(std::string language);
|
||||||
|
@ -160,8 +153,7 @@ u32 getMainWindowGeometryX();
|
||||||
u32 getMainWindowGeometryY();
|
u32 getMainWindowGeometryY();
|
||||||
u32 getMainWindowGeometryW();
|
u32 getMainWindowGeometryW();
|
||||||
u32 getMainWindowGeometryH();
|
u32 getMainWindowGeometryH();
|
||||||
const std::vector<std::filesystem::path> getGameInstallDirs();
|
const std::vector<std::filesystem::path>& getGameInstallDirs();
|
||||||
const std::vector<bool> getGameInstallDirsEnabled();
|
|
||||||
std::filesystem::path getAddonInstallDir();
|
std::filesystem::path getAddonInstallDir();
|
||||||
u32 getMainWindowTheme();
|
u32 getMainWindowTheme();
|
||||||
u32 getIconSize();
|
u32 getIconSize();
|
||||||
|
@ -171,6 +163,7 @@ u32 getSliderPositionGrid();
|
||||||
u32 getTableMode();
|
u32 getTableMode();
|
||||||
u32 getMainWindowWidth();
|
u32 getMainWindowWidth();
|
||||||
u32 getMainWindowHeight();
|
u32 getMainWindowHeight();
|
||||||
|
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();
|
std::string getEmulatorLanguage();
|
||||||
|
|
|
@ -125,13 +125,12 @@ namespace {
|
||||||
[[nodiscard]] constexpr int ToSeekOrigin(SeekOrigin origin) {
|
[[nodiscard]] constexpr int ToSeekOrigin(SeekOrigin origin) {
|
||||||
switch (origin) {
|
switch (origin) {
|
||||||
case SeekOrigin::SetOrigin:
|
case SeekOrigin::SetOrigin:
|
||||||
|
default:
|
||||||
return SEEK_SET;
|
return SEEK_SET;
|
||||||
case SeekOrigin::CurrentPosition:
|
case SeekOrigin::CurrentPosition:
|
||||||
return SEEK_CUR;
|
return SEEK_CUR;
|
||||||
case SeekOrigin::End:
|
case SeekOrigin::End:
|
||||||
return SEEK_END;
|
return SEEK_END;
|
||||||
default:
|
|
||||||
UNREACHABLE_MSG("Impossible SeekOrigin {}", static_cast<u32>(origin));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -378,6 +377,20 @@ bool IOFile::Seek(s64 offset, SeekOrigin origin) const {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (False(file_access_mode & (FileAccessMode::Write | FileAccessMode::Append))) {
|
||||||
|
u64 size = GetSize();
|
||||||
|
if (origin == SeekOrigin::CurrentPosition && Tell() + offset > size) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
|
||||||
|
return false;
|
||||||
|
} else if (origin == SeekOrigin::SetOrigin && (u64)offset > size) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
|
||||||
|
return false;
|
||||||
|
} else if (origin == SeekOrigin::End && offset > 0) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Seeking past the end of the file");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0;
|
const auto seek_result = fseeko(file, offset, ToSeekOrigin(origin)) == 0;
|
||||||
|
|
|
@ -101,7 +101,6 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||||
SUB(Lib, Ssl2) \
|
SUB(Lib, Ssl2) \
|
||||||
SUB(Lib, SysModule) \
|
SUB(Lib, SysModule) \
|
||||||
SUB(Lib, Move) \
|
SUB(Lib, Move) \
|
||||||
SUB(Lib, NpAuth) \
|
|
||||||
SUB(Lib, NpCommon) \
|
SUB(Lib, NpCommon) \
|
||||||
SUB(Lib, NpManager) \
|
SUB(Lib, NpManager) \
|
||||||
SUB(Lib, NpScore) \
|
SUB(Lib, NpScore) \
|
||||||
|
|
|
@ -69,7 +69,6 @@ enum class Class : u8 {
|
||||||
Lib_Http2, ///< The LibSceHttp2 implementation.
|
Lib_Http2, ///< The LibSceHttp2 implementation.
|
||||||
Lib_SysModule, ///< The LibSceSysModule implementation
|
Lib_SysModule, ///< The LibSceSysModule implementation
|
||||||
Lib_NpCommon, ///< The LibSceNpCommon implementation
|
Lib_NpCommon, ///< The LibSceNpCommon implementation
|
||||||
Lib_NpAuth, ///< The LibSceNpAuth implementation
|
|
||||||
Lib_NpManager, ///< The LibSceNpManager implementation
|
Lib_NpManager, ///< The LibSceNpManager implementation
|
||||||
Lib_NpScore, ///< The LibSceNpScore implementation
|
Lib_NpScore, ///< The LibSceNpScore implementation
|
||||||
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace MemoryPatcher {
|
namespace MemoryPatcher {
|
||||||
|
|
||||||
EXPORT uintptr_t g_eboot_address;
|
uintptr_t g_eboot_address;
|
||||||
uint64_t g_eboot_image_size;
|
uint64_t g_eboot_image_size;
|
||||||
std::string g_game_serial;
|
std::string g_game_serial;
|
||||||
std::string patchFile;
|
std::string patchFile;
|
||||||
|
@ -169,8 +169,7 @@ void OnGameLoaded() {
|
||||||
if (type == "mask_jump32")
|
if (type == "mask_jump32")
|
||||||
patchMask = MemoryPatcher::PatchMask::Mask_Jump32;
|
patchMask = MemoryPatcher::PatchMask::Mask_Jump32;
|
||||||
|
|
||||||
if ((type == "mask" || type == "mask_jump32") &&
|
if (type == "mask" || type == "mask_jump32" && !maskOffsetStr.empty()) {
|
||||||
!maskOffsetStr.empty()) {
|
|
||||||
maskOffsetValue = std::stoi(maskOffsetStr, 0, 10);
|
maskOffsetValue = std::stoi(maskOffsetStr, 0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#if defined(WIN32)
|
|
||||||
#define EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define EXPORT __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace MemoryPatcher {
|
namespace MemoryPatcher {
|
||||||
|
|
||||||
extern EXPORT uintptr_t g_eboot_address;
|
extern uintptr_t g_eboot_address;
|
||||||
extern uint64_t g_eboot_image_size;
|
extern uint64_t g_eboot_image_size;
|
||||||
extern std::string g_game_serial;
|
extern std::string g_game_serial;
|
||||||
extern std::string patchFile;
|
extern std::string patchFile;
|
||||||
|
|
|
@ -60,7 +60,7 @@ static CFURLRef UntranslocateBundlePath(const CFURLRef bundle_path) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::optional<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 {
|
||||||
|
@ -83,16 +83,14 @@ static std::optional<std::filesystem::path> GetBundleParentDirectory() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
return std::filesystem::current_path();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static auto UserPaths = [] {
|
static auto UserPaths = [] {
|
||||||
#if defined(__APPLE__) && defined(ENABLE_QT_GUI)
|
#ifdef __APPLE__
|
||||||
// Set the current path to the directory containing the app bundle.
|
// Set the current path to the directory containing the app bundle.
|
||||||
if (const auto bundle_dir = GetBundleParentDirectory()) {
|
std::filesystem::current_path(GetBundleParentDirectory());
|
||||||
std::filesystem::current_path(*bundle_dir);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try the portable user directory first.
|
// Try the portable user directory first.
|
||||||
|
|
|
@ -3,17 +3,21 @@
|
||||||
|
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
|
||||||
|
#define GIT_REV "@GIT_REV@"
|
||||||
|
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||||
|
#define GIT_DESC "@GIT_DESC@"
|
||||||
|
#define GIT_REMOTE_NAME "@GIT_REMOTE_NAME@"
|
||||||
|
#define GIT_REMOTE_URL "@GIT_REMOTE_URL@"
|
||||||
|
#define BUILD_DATE "@BUILD_DATE@"
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
constexpr char g_version[] = "@APP_VERSION@";
|
const char g_scm_rev[] = GIT_REV;
|
||||||
constexpr bool g_is_release = @APP_IS_RELEASE@;
|
const char g_scm_branch[] = GIT_BRANCH;
|
||||||
|
const char g_scm_desc[] = GIT_DESC;
|
||||||
constexpr char g_scm_rev[] = "@GIT_REV@";
|
const char g_scm_remote_name[] = GIT_REMOTE_NAME;
|
||||||
constexpr char g_scm_branch[] = "@GIT_BRANCH@";
|
const char g_scm_remote_url[] = GIT_REMOTE_URL;
|
||||||
constexpr char g_scm_desc[] = "@GIT_DESC@";
|
const char g_scm_date[] = BUILD_DATE;
|
||||||
constexpr char g_scm_remote_name[] = "@GIT_REMOTE_NAME@";
|
|
||||||
constexpr char g_scm_remote_url[] = "@GIT_REMOTE_URL@";
|
|
||||||
constexpr char g_scm_date[] = "@BUILD_DATE@";
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,6 @@
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
extern const char g_version[];
|
|
||||||
extern const bool g_is_release;
|
|
||||||
|
|
||||||
extern const char g_scm_rev[];
|
extern const char g_scm_rev[];
|
||||||
extern const char g_scm_branch[];
|
extern const char g_scm_branch[];
|
||||||
extern const char g_scm_desc[];
|
extern const char g_scm_desc[];
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2012 SAURAV MOHAPATRA <mohaps@gmail.com>
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace sha1 {
|
|
||||||
class SHA1 {
|
|
||||||
public:
|
|
||||||
typedef uint32_t digest32_t[5];
|
|
||||||
typedef uint8_t digest8_t[20];
|
|
||||||
inline static uint32_t LeftRotate(uint32_t value, size_t count) {
|
|
||||||
return (value << count) ^ (value >> (32 - count));
|
|
||||||
}
|
|
||||||
SHA1() {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
virtual ~SHA1() {}
|
|
||||||
SHA1(const SHA1& s) {
|
|
||||||
*this = s;
|
|
||||||
}
|
|
||||||
const SHA1& operator=(const SHA1& s) {
|
|
||||||
memcpy(m_digest, s.m_digest, 5 * sizeof(uint32_t));
|
|
||||||
memcpy(m_block, s.m_block, 64);
|
|
||||||
m_blockByteIndex = s.m_blockByteIndex;
|
|
||||||
m_byteCount = s.m_byteCount;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
SHA1& reset() {
|
|
||||||
m_digest[0] = 0x67452301;
|
|
||||||
m_digest[1] = 0xEFCDAB89;
|
|
||||||
m_digest[2] = 0x98BADCFE;
|
|
||||||
m_digest[3] = 0x10325476;
|
|
||||||
m_digest[4] = 0xC3D2E1F0;
|
|
||||||
m_blockByteIndex = 0;
|
|
||||||
m_byteCount = 0;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
SHA1& processByte(uint8_t octet) {
|
|
||||||
this->m_block[this->m_blockByteIndex++] = octet;
|
|
||||||
++this->m_byteCount;
|
|
||||||
if (m_blockByteIndex == 64) {
|
|
||||||
this->m_blockByteIndex = 0;
|
|
||||||
processBlock();
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
SHA1& processBlock(const void* const start, const void* const end) {
|
|
||||||
const uint8_t* begin = static_cast<const uint8_t*>(start);
|
|
||||||
const uint8_t* finish = static_cast<const uint8_t*>(end);
|
|
||||||
while (begin != finish) {
|
|
||||||
processByte(*begin);
|
|
||||||
begin++;
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
SHA1& processBytes(const void* const data, size_t len) {
|
|
||||||
const uint8_t* block = static_cast<const uint8_t*>(data);
|
|
||||||
processBlock(block, block + len);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
const uint32_t* getDigest(digest32_t digest) {
|
|
||||||
size_t bitCount = this->m_byteCount * 8;
|
|
||||||
processByte(0x80);
|
|
||||||
if (this->m_blockByteIndex > 56) {
|
|
||||||
while (m_blockByteIndex != 0) {
|
|
||||||
processByte(0);
|
|
||||||
}
|
|
||||||
while (m_blockByteIndex < 56) {
|
|
||||||
processByte(0);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (m_blockByteIndex < 56) {
|
|
||||||
processByte(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
processByte(0);
|
|
||||||
processByte(0);
|
|
||||||
processByte(0);
|
|
||||||
processByte(0);
|
|
||||||
processByte(static_cast<unsigned char>((bitCount >> 24) & 0xFF));
|
|
||||||
processByte(static_cast<unsigned char>((bitCount >> 16) & 0xFF));
|
|
||||||
processByte(static_cast<unsigned char>((bitCount >> 8) & 0xFF));
|
|
||||||
processByte(static_cast<unsigned char>((bitCount) & 0xFF));
|
|
||||||
|
|
||||||
memcpy(digest, m_digest, 5 * sizeof(uint32_t));
|
|
||||||
return digest;
|
|
||||||
}
|
|
||||||
const uint8_t* getDigestBytes(digest8_t digest) {
|
|
||||||
digest32_t d32;
|
|
||||||
getDigest(d32);
|
|
||||||
size_t di = 0;
|
|
||||||
digest[di++] = ((d32[0] >> 24) & 0xFF);
|
|
||||||
digest[di++] = ((d32[0] >> 16) & 0xFF);
|
|
||||||
digest[di++] = ((d32[0] >> 8) & 0xFF);
|
|
||||||
digest[di++] = ((d32[0]) & 0xFF);
|
|
||||||
|
|
||||||
digest[di++] = ((d32[1] >> 24) & 0xFF);
|
|
||||||
digest[di++] = ((d32[1] >> 16) & 0xFF);
|
|
||||||
digest[di++] = ((d32[1] >> 8) & 0xFF);
|
|
||||||
digest[di++] = ((d32[1]) & 0xFF);
|
|
||||||
|
|
||||||
digest[di++] = ((d32[2] >> 24) & 0xFF);
|
|
||||||
digest[di++] = ((d32[2] >> 16) & 0xFF);
|
|
||||||
digest[di++] = ((d32[2] >> 8) & 0xFF);
|
|
||||||
digest[di++] = ((d32[2]) & 0xFF);
|
|
||||||
|
|
||||||
digest[di++] = ((d32[3] >> 24) & 0xFF);
|
|
||||||
digest[di++] = ((d32[3] >> 16) & 0xFF);
|
|
||||||
digest[di++] = ((d32[3] >> 8) & 0xFF);
|
|
||||||
digest[di++] = ((d32[3]) & 0xFF);
|
|
||||||
|
|
||||||
digest[di++] = ((d32[4] >> 24) & 0xFF);
|
|
||||||
digest[di++] = ((d32[4] >> 16) & 0xFF);
|
|
||||||
digest[di++] = ((d32[4] >> 8) & 0xFF);
|
|
||||||
digest[di++] = ((d32[4]) & 0xFF);
|
|
||||||
return digest;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void processBlock() {
|
|
||||||
uint32_t w[80];
|
|
||||||
for (size_t i = 0; i < 16; i++) {
|
|
||||||
w[i] = (m_block[i * 4 + 0] << 24);
|
|
||||||
w[i] |= (m_block[i * 4 + 1] << 16);
|
|
||||||
w[i] |= (m_block[i * 4 + 2] << 8);
|
|
||||||
w[i] |= (m_block[i * 4 + 3]);
|
|
||||||
}
|
|
||||||
for (size_t i = 16; i < 80; i++) {
|
|
||||||
w[i] = LeftRotate((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t a = m_digest[0];
|
|
||||||
uint32_t b = m_digest[1];
|
|
||||||
uint32_t c = m_digest[2];
|
|
||||||
uint32_t d = m_digest[3];
|
|
||||||
uint32_t e = m_digest[4];
|
|
||||||
|
|
||||||
for (std::size_t i = 0; i < 80; ++i) {
|
|
||||||
uint32_t f = 0;
|
|
||||||
uint32_t k = 0;
|
|
||||||
|
|
||||||
if (i < 20) {
|
|
||||||
f = (b & c) | (~b & d);
|
|
||||||
k = 0x5A827999;
|
|
||||||
} else if (i < 40) {
|
|
||||||
f = b ^ c ^ d;
|
|
||||||
k = 0x6ED9EBA1;
|
|
||||||
} else if (i < 60) {
|
|
||||||
f = (b & c) | (b & d) | (c & d);
|
|
||||||
k = 0x8F1BBCDC;
|
|
||||||
} else {
|
|
||||||
f = b ^ c ^ d;
|
|
||||||
k = 0xCA62C1D6;
|
|
||||||
}
|
|
||||||
uint32_t temp = LeftRotate(a, 5) + f + e + k + w[i];
|
|
||||||
e = d;
|
|
||||||
d = c;
|
|
||||||
c = LeftRotate(b, 30);
|
|
||||||
b = a;
|
|
||||||
a = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_digest[0] += a;
|
|
||||||
m_digest[1] += b;
|
|
||||||
m_digest[2] += c;
|
|
||||||
m_digest[3] += d;
|
|
||||||
m_digest[4] += e;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
digest32_t m_digest;
|
|
||||||
uint8_t m_block[64];
|
|
||||||
size_t m_blockByteIndex;
|
|
||||||
size_t m_byteCount;
|
|
||||||
};
|
|
||||||
} // namespace sha1
|
|
14
src/common/version.h
Normal file
14
src/common/version.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
namespace Common {
|
||||||
|
|
||||||
|
constexpr char VERSION[] = "0.7.0";
|
||||||
|
constexpr bool isRelease = true;
|
||||||
|
|
||||||
|
} // namespace Common
|
|
@ -19,6 +19,8 @@ enum class MemoryPermission : u32 {
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission)
|
DECLARE_ENUM_FLAG_OPERATORS(MemoryPermission)
|
||||||
|
|
||||||
|
constexpr VAddr CODE_BASE_OFFSET = 0x100000000ULL;
|
||||||
|
|
||||||
constexpr VAddr SYSTEM_MANAGED_MIN = 0x00000400000ULL;
|
constexpr VAddr SYSTEM_MANAGED_MIN = 0x00000400000ULL;
|
||||||
constexpr VAddr SYSTEM_MANAGED_MAX = 0x07FFFFBFFFULL;
|
constexpr VAddr SYSTEM_MANAGED_MAX = 0x07FFFFBFFFULL;
|
||||||
constexpr VAddr SYSTEM_RESERVED_MIN = 0x07FFFFC000ULL;
|
constexpr VAddr SYSTEM_RESERVED_MIN = 0x07FFFFC000ULL;
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <half.hpp>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
@ -77,6 +81,538 @@ 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) {
|
||||||
|
switch (operand.type) {
|
||||||
|
case ZYDIS_OPERAND_TYPE_REGISTER: {
|
||||||
|
return std::make_unique<Xbyak::Reg>(ZydisToXbyakRegisterOperand(operand));
|
||||||
|
}
|
||||||
|
case ZYDIS_OPERAND_TYPE_MEMORY: {
|
||||||
|
return std::make_unique<Xbyak::Address>(ZydisToXbyakMemoryOperand(operand));
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE_MSG("Unsupported operand type: {}", static_cast<u32>(operand.type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool OperandUsesRegister(const Xbyak::Operand* operand, int index) {
|
||||||
|
if (operand->isREG()) {
|
||||||
|
return operand->getIdx() == index;
|
||||||
|
}
|
||||||
|
if (operand->isMEM()) {
|
||||||
|
const Xbyak::RegExp& reg_exp = operand->getAddress().getRegExp();
|
||||||
|
return reg_exp.getBase().getIdx() == index || reg_exp.getIndex().getIdx() == index;
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("Unsupported operand kind: {}", static_cast<u32>(operand->getKind()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsRegisterAllocated(
|
||||||
|
const std::initializer_list<const Xbyak::Operand*>& allocated_registers, const int index) {
|
||||||
|
return std::ranges::find_if(allocated_registers.begin(), allocated_registers.end(),
|
||||||
|
[index](const Xbyak::Operand* operand) {
|
||||||
|
return OperandUsesRegister(operand, index);
|
||||||
|
}) != allocated_registers.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Xbyak::Reg AllocateScratchRegister(
|
||||||
|
const std::initializer_list<const Xbyak::Operand*> allocated_registers, const u32 bits) {
|
||||||
|
for (int index = Xbyak::Operand::R8; index <= Xbyak::Operand::R15; index++) {
|
||||||
|
if (!IsRegisterAllocated(allocated_registers, index)) {
|
||||||
|
return Xbyak::Reg32e(index, static_cast<int>(bits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNREACHABLE_MSG("Out of scratch registers!");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
static pthread_key_t stack_pointer_slot;
|
||||||
|
static pthread_key_t patch_stack_slot;
|
||||||
|
static std::once_flag patch_context_slots_init_flag;
|
||||||
|
static constexpr u32 patch_stack_size = 0x1000;
|
||||||
|
|
||||||
|
static_assert(sizeof(void*) == sizeof(u64),
|
||||||
|
"Cannot fit a register inside a thread local storage slot.");
|
||||||
|
|
||||||
|
static void FreePatchStack(void* patch_stack) {
|
||||||
|
// Subtract back to the bottom of the stack for free.
|
||||||
|
std::free(static_cast<u8*>(patch_stack) - patch_stack_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void InitializePatchContextSlots() {
|
||||||
|
ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0,
|
||||||
|
"Unable to allocate thread-local register for stack pointer.");
|
||||||
|
ASSERT_MSG(pthread_key_create(&patch_stack_slot, FreePatchStack) == 0,
|
||||||
|
"Unable to allocate thread-local register for patch stack.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitializeThreadPatchStack() {
|
||||||
|
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||||
|
|
||||||
|
pthread_setspecific(patch_stack_slot,
|
||||||
|
static_cast<u8*>(std::malloc(patch_stack_size)) + patch_stack_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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 original 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*))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validates that the dst register is supported given the SaveStack/RestoreStack implementation.
|
||||||
|
static void ValidateDst(const Xbyak::Reg& dst) {
|
||||||
|
// No restrictions.
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void InitializeThreadPatchStack() {
|
||||||
|
// No-op
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Since stack pointer here is subtracted through safe zone and not saved anywhere,
|
||||||
|
// it must not be modified during the instruction. Otherwise, we will not be able to find
|
||||||
|
// and load registers back from where they were saved. Thus, a limitation is placed on
|
||||||
|
// instructions, that they must not use the stack pointer register as a destination.
|
||||||
|
|
||||||
|
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||||
|
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||||
|
c.lea(rsp, ptr[rsp - 128]); // red zone
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restores the stack pointer from thread local storage.
|
||||||
|
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||||
|
c.lea(rsp, ptr[rsp + 128]); // red zone
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Validates that the dst register is supported given the SaveStack/RestoreStack implementation.
|
||||||
|
static void ValidateDst(const Xbyak::Reg& dst) {
|
||||||
|
// Stack pointer is not preserved, so it can't be used as a dst.
|
||||||
|
ASSERT_MSG(dst.getIdx() != rsp.getIdx(), "Stack pointer not supported as destination.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#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) {
|
||||||
|
// Uses a more robust solution for saving registers on MacOS to avoid potential stack corruption
|
||||||
|
// if games decide to not follow the ABI and use the red zone.
|
||||||
|
SaveStack(c);
|
||||||
|
for (const auto& reg : regs) {
|
||||||
|
c.push(reg.cvt64());
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Switches to the patch stack, restores registers, and restores the original stack.
|
||||||
|
static void RestoreRegisters(Xbyak::CodeGenerator& c,
|
||||||
|
const std::initializer_list<Xbyak::Reg> regs) {
|
||||||
|
SaveStack(c);
|
||||||
|
for (const auto& reg : regs) {
|
||||||
|
c.pop(reg.cvt64());
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Switches to the patch stack and stores all registers.
|
||||||
|
static void SaveContext(Xbyak::CodeGenerator& c, bool save_flags = false) {
|
||||||
|
SaveStack(c);
|
||||||
|
for (int reg = Xbyak::Operand::RAX; reg <= Xbyak::Operand::R15; reg++) {
|
||||||
|
c.push(Xbyak::Reg64(reg));
|
||||||
|
}
|
||||||
|
c.lea(rsp, ptr[rsp - 32 * 16]);
|
||||||
|
for (int reg = 0; reg <= 15; reg++) {
|
||||||
|
c.vmovdqu(ptr[rsp + 32 * reg], Xbyak::Ymm(reg));
|
||||||
|
}
|
||||||
|
if (save_flags) {
|
||||||
|
c.pushfq();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 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,
|
||||||
|
bool restore_flags = false) {
|
||||||
|
if (restore_flags) {
|
||||||
|
c.popfq();
|
||||||
|
}
|
||||||
|
for (int reg = 15; reg >= 0; reg--) {
|
||||||
|
if ((!dst.isXMM() && !dst.isYMM()) || dst.getIdx() != reg) {
|
||||||
|
c.vmovdqu(Xbyak::Ymm(reg), ptr[rsp + 32 * reg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.lea(rsp, ptr[rsp + 32 * 16]);
|
||||||
|
for (int reg = Xbyak::Operand::R15; reg >= Xbyak::Operand::RAX; reg--) {
|
||||||
|
if (!dst.isREG() || dst.getIdx() != reg) {
|
||||||
|
c.pop(Xbyak::Reg64(reg));
|
||||||
|
} else {
|
||||||
|
c.lea(rsp, ptr[rsp + 8]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RestoreStack(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
|
||||||
|
const auto src2 = ZydisToXbyakOperand(operands[2]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
// Check if src2 is a memory operand or a register different to dst.
|
||||||
|
// In those cases, we don't need to use a temporary register and are free to modify dst.
|
||||||
|
// In cases where dst and src2 are the same register, a temporary needs to be used to avoid
|
||||||
|
// modifying src2.
|
||||||
|
bool src2_uses_dst = false;
|
||||||
|
if (src2->isMEM()) {
|
||||||
|
const auto base = src2->getAddress().getRegExp().getBase().getIdx();
|
||||||
|
const auto index = src2->getAddress().getRegExp().getIndex().getIdx();
|
||||||
|
src2_uses_dst = base == dst.getIdx() || index == dst.getIdx();
|
||||||
|
} else {
|
||||||
|
ASSERT(src2->isREG());
|
||||||
|
src2_uses_dst = src2->getReg() == dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src2_uses_dst) {
|
||||||
|
if (dst != src1)
|
||||||
|
c.mov(dst, src1);
|
||||||
|
c.not_(dst);
|
||||||
|
c.and_(dst, *src2);
|
||||||
|
} else {
|
||||||
|
const auto scratch = AllocateScratchRegister({&dst, &src1, src2.get()}, dst.getBit());
|
||||||
|
|
||||||
|
SaveRegisters(c, {scratch});
|
||||||
|
|
||||||
|
c.mov(scratch, src1);
|
||||||
|
c.not_(scratch);
|
||||||
|
c.and_(scratch, *src2);
|
||||||
|
c.mov(dst, scratch);
|
||||||
|
|
||||||
|
RestoreRegisters(c, {scratch});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
const auto start_len = ZydisToXbyakRegisterOperand(operands[2]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
const Xbyak::Reg32e shift(Xbyak::Operand::RCX, static_cast<int>(start_len.getBit()));
|
||||||
|
const auto scratch1 =
|
||||||
|
AllocateScratchRegister({&dst, src.get(), &start_len, &shift}, dst.getBit());
|
||||||
|
const auto scratch2 =
|
||||||
|
AllocateScratchRegister({&dst, src.get(), &start_len, &shift, &scratch1}, dst.getBit());
|
||||||
|
|
||||||
|
if (dst.getIdx() == shift.getIdx()) {
|
||||||
|
SaveRegisters(c, {scratch1, scratch2});
|
||||||
|
} else {
|
||||||
|
SaveRegisters(c, {scratch1, scratch2, shift});
|
||||||
|
}
|
||||||
|
|
||||||
|
c.mov(scratch1, *src);
|
||||||
|
if (shift.getIdx() != start_len.getIdx()) {
|
||||||
|
c.mov(shift, start_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
c.shr(scratch1, shift.cvt8());
|
||||||
|
c.shr(shift, 8);
|
||||||
|
c.mov(scratch2, 1);
|
||||||
|
c.shl(scratch2, shift.cvt8());
|
||||||
|
c.dec(scratch2);
|
||||||
|
|
||||||
|
c.mov(dst, scratch1);
|
||||||
|
c.and_(dst, scratch2);
|
||||||
|
|
||||||
|
if (dst.getIdx() == shift.getIdx()) {
|
||||||
|
RestoreRegisters(c, {scratch2, scratch1});
|
||||||
|
} else {
|
||||||
|
RestoreRegisters(c, {shift, scratch2, scratch1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateBLSI(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||||
|
|
||||||
|
SaveRegisters(c, {scratch});
|
||||||
|
|
||||||
|
// BLSI sets CF to zero if source is zero, otherwise it sets CF to one.
|
||||||
|
Xbyak::Label clear_carry, end;
|
||||||
|
|
||||||
|
c.mov(scratch, *src);
|
||||||
|
c.neg(scratch); // NEG, like BLSI, clears CF if the source is zero and sets it otherwise
|
||||||
|
c.jnc(clear_carry);
|
||||||
|
|
||||||
|
c.and_(scratch, *src);
|
||||||
|
c.stc(); // setting/clearing carry needs to happen after the AND because that clears CF
|
||||||
|
c.jmp(end);
|
||||||
|
|
||||||
|
c.L(clear_carry);
|
||||||
|
c.and_(scratch, *src);
|
||||||
|
// We don't need to clear carry here since AND does that for us
|
||||||
|
|
||||||
|
c.L(end);
|
||||||
|
c.mov(dst, scratch);
|
||||||
|
|
||||||
|
RestoreRegisters(c, {scratch});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateBLSMSK(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||||
|
|
||||||
|
SaveRegisters(c, {scratch});
|
||||||
|
|
||||||
|
Xbyak::Label clear_carry, end;
|
||||||
|
|
||||||
|
// BLSMSK sets CF to zero if source is NOT zero, otherwise it sets CF to one.
|
||||||
|
c.mov(scratch, *src);
|
||||||
|
c.test(scratch, scratch);
|
||||||
|
c.jnz(clear_carry);
|
||||||
|
|
||||||
|
c.dec(scratch);
|
||||||
|
c.xor_(scratch, *src);
|
||||||
|
c.stc();
|
||||||
|
c.jmp(end);
|
||||||
|
|
||||||
|
c.L(clear_carry);
|
||||||
|
c.dec(scratch);
|
||||||
|
c.xor_(scratch, *src);
|
||||||
|
// We don't need to clear carry here since XOR does that for us
|
||||||
|
|
||||||
|
c.L(end);
|
||||||
|
c.mov(dst, scratch);
|
||||||
|
|
||||||
|
RestoreRegisters(c, {scratch});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateTZCNT(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
Xbyak::Label src_zero, end;
|
||||||
|
|
||||||
|
c.cmp(*src, 0);
|
||||||
|
c.je(src_zero);
|
||||||
|
|
||||||
|
// If src is not zero, functions like a BSF, but also clears the CF
|
||||||
|
c.bsf(dst, *src);
|
||||||
|
c.clc();
|
||||||
|
c.jmp(end);
|
||||||
|
|
||||||
|
c.L(src_zero);
|
||||||
|
c.mov(dst, operands[0].size);
|
||||||
|
// Since dst is not zero, also set ZF to zero. Testing dst with itself when we know
|
||||||
|
// it isn't zero is a good way to do this.
|
||||||
|
// Use cvt32 to avoid REX/Operand size prefixes.
|
||||||
|
c.test(dst.cvt32(), dst.cvt32());
|
||||||
|
// When source is zero, TZCNT also sets CF.
|
||||||
|
c.stc();
|
||||||
|
|
||||||
|
c.L(end);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
ValidateDst(dst);
|
||||||
|
|
||||||
|
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||||
|
|
||||||
|
SaveRegisters(c, {scratch});
|
||||||
|
|
||||||
|
Xbyak::Label clear_carry, end;
|
||||||
|
|
||||||
|
// BLSR sets CF to zero if source is NOT zero, otherwise it sets CF to one.
|
||||||
|
c.mov(scratch, *src);
|
||||||
|
c.test(scratch, scratch);
|
||||||
|
c.jnz(clear_carry);
|
||||||
|
|
||||||
|
c.dec(scratch);
|
||||||
|
c.and_(scratch, *src);
|
||||||
|
c.stc();
|
||||||
|
c.jmp(end);
|
||||||
|
|
||||||
|
c.L(clear_carry);
|
||||||
|
c.dec(scratch);
|
||||||
|
c.and_(scratch, *src);
|
||||||
|
// We don't need to clear carry here since AND does that for us
|
||||||
|
|
||||||
|
c.L(end);
|
||||||
|
c.mov(dst, scratch);
|
||||||
|
|
||||||
|
RestoreRegisters(c, {scratch});
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
static __attribute__((sysv_abi)) void PerformVCVTPH2PS(float* out, const half_float::half* in,
|
||||||
|
const u32 count) {
|
||||||
|
for (u32 i = 0; i < count; i++) {
|
||||||
|
out[i] = half_float::half_cast<float>(in[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GenerateVCVTPH2PS(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
|
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||||
|
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||||
|
|
||||||
|
const auto float_count = dst.getBit() / 32;
|
||||||
|
const auto byte_count = float_count * 4;
|
||||||
|
|
||||||
|
SaveContext(c, true);
|
||||||
|
|
||||||
|
// 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, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
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, true);
|
||||||
|
|
||||||
|
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, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
||||||
|
int ret = 0;
|
||||||
|
size_t size = sizeof(ret);
|
||||||
|
if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // __APPLE__
|
||||||
|
|
||||||
static bool FilterTcbAccess(const ZydisDecodedOperand* operands) {
|
static bool FilterTcbAccess(const ZydisDecodedOperand* operands) {
|
||||||
const auto& dst_op = operands[0];
|
const auto& dst_op = operands[0];
|
||||||
const auto& src_op = operands[1];
|
const auto& src_op = operands[1];
|
||||||
|
@ -121,11 +657,18 @@ static void GenerateTcbAccess(const ZydisDecodedOperand* operands, Xbyak::CodeGe
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
static bool FilterNoSSE4a(const ZydisDecodedOperand*) {
|
static bool FilterNoSSE4a(const ZydisDecodedOperand*) {
|
||||||
Cpu cpu;
|
Cpu cpu;
|
||||||
return !cpu.has(Cpu::tSSE4a);
|
return !cpu.has(Cpu::tSSE4a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool FilterNoBMI1(const ZydisDecodedOperand*) {
|
||||||
|
Cpu cpu;
|
||||||
|
return !cpu.has(Cpu::tBMI1);
|
||||||
|
}
|
||||||
|
|
||||||
static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||||
bool immediateForm = operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
bool immediateForm = operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||||
operands[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
operands[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||||
|
@ -397,16 +940,30 @@ struct PatchInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
||||||
// SSE4a
|
|
||||||
{ZYDIS_MNEMONIC_EXTRQ, {FilterNoSSE4a, GenerateEXTRQ, true}},
|
|
||||||
{ZYDIS_MNEMONIC_INSERTQ, {FilterNoSSE4a, GenerateINSERTQ, true}},
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
// Windows needs a trampoline.
|
// Windows needs a trampoline.
|
||||||
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, true}},
|
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, true}},
|
||||||
#elif !defined(__APPLE__)
|
#elif !defined(__APPLE__)
|
||||||
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, false}},
|
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, false}},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
{ZYDIS_MNEMONIC_EXTRQ, {FilterNoSSE4a, GenerateEXTRQ, true}},
|
||||||
|
{ZYDIS_MNEMONIC_INSERTQ, {FilterNoSSE4a, GenerateINSERTQ, true}},
|
||||||
|
|
||||||
|
// BMI1
|
||||||
|
{ZYDIS_MNEMONIC_ANDN, {FilterNoBMI1, GenerateANDN, true}},
|
||||||
|
{ZYDIS_MNEMONIC_BEXTR, {FilterNoBMI1, GenerateBEXTR, true}},
|
||||||
|
{ZYDIS_MNEMONIC_BLSI, {FilterNoBMI1, GenerateBLSI, true}},
|
||||||
|
{ZYDIS_MNEMONIC_BLSMSK, {FilterNoBMI1, GenerateBLSMSK, true}},
|
||||||
|
{ZYDIS_MNEMONIC_BLSR, {FilterNoBMI1, GenerateBLSR, true}},
|
||||||
|
{ZYDIS_MNEMONIC_TZCNT, {FilterNoBMI1, GenerateTZCNT, true}},
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
// Patches for instruction sets not supported by Rosetta 2.
|
||||||
|
// F16C
|
||||||
|
{ZYDIS_MNEMONIC_VCVTPH2PS, {FilterRosetta2Only, GenerateVCVTPH2PS, true}},
|
||||||
|
{ZYDIS_MNEMONIC_VCVTPS2PH, {FilterRosetta2Only, GenerateVCVTPS2PH, true}},
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::once_flag init_flag;
|
static std::once_flag init_flag;
|
||||||
|
@ -723,7 +1280,18 @@ void RegisterPatchModule(void* module_ptr, u64 module_size, void* trampoline_are
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrePatchInstructions(u64 segment_addr, u64 segment_size) {
|
void PrePatchInstructions(u64 segment_addr, u64 segment_size) {
|
||||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
// HACK: For some reason patching in the signal handler at the start of a page does not work
|
||||||
|
// under Rosetta 2. Patch any instructions at the start of a page ahead of time.
|
||||||
|
if (!Patches.empty()) {
|
||||||
|
auto* code_page = reinterpret_cast<u8*>(Common::AlignUp(segment_addr, 0x1000));
|
||||||
|
const auto* end_page = code_page + Common::AlignUp(segment_size, 0x1000);
|
||||||
|
while (code_page < end_page) {
|
||||||
|
TryPatchJit(code_page);
|
||||||
|
code_page += 0x1000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#elif !defined(_WIN32)
|
||||||
// Linux and others have an FS segment pointing to valid memory, so continue to do full
|
// Linux and others have an FS segment pointing to valid memory, so continue to do full
|
||||||
// ahead-of-time patching for now until a better solution is worked out.
|
// ahead-of-time patching for now until a better solution is worked out.
|
||||||
if (!Patches.empty()) {
|
if (!Patches.empty()) {
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
/// Registers a module for patching, providing an area to generate trampoline code.
|
/// Registers a module for patching, providing an area to generate trampoline code.
|
||||||
void RegisterPatchModule(void* module_ptr, u64 module_size, void* trampoline_area_ptr,
|
void RegisterPatchModule(void* module_ptr, u64 module_size, void* trampoline_area_ptr,
|
||||||
u64 trampoline_area_size);
|
u64 trampoline_area_size);
|
||||||
|
|
215
src/core/crypto/crypto.cpp
Normal file
215
src/core/crypto/crypto.cpp
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
#include "crypto.h"
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
||||||
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
|
params.SetPrime1(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime1, 0x80));
|
||||||
|
params.SetPrime2(CryptoPP::Integer(PkgDerivedKey3Keyset::Prime2, 0x80));
|
||||||
|
|
||||||
|
params.SetPublicExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PublicExponent, 4));
|
||||||
|
params.SetPrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::PrivateExponent, 0x100));
|
||||||
|
|
||||||
|
params.SetModPrime1PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent1, 0x80));
|
||||||
|
params.SetModPrime2PrivateExponent(CryptoPP::Integer(PkgDerivedKey3Keyset::Exponent2, 0x80));
|
||||||
|
|
||||||
|
params.SetModulus(CryptoPP::Integer(PkgDerivedKey3Keyset::Modulus, 0x100));
|
||||||
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
|
CryptoPP::Integer(PkgDerivedKey3Keyset::Coefficient, 0x80));
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey Crypto::FakeKeyset_keyset_init() {
|
||||||
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
|
params.SetPrime1(CryptoPP::Integer(FakeKeyset::Prime1, 0x80));
|
||||||
|
params.SetPrime2(CryptoPP::Integer(FakeKeyset::Prime2, 0x80));
|
||||||
|
|
||||||
|
params.SetPublicExponent(CryptoPP::Integer(FakeKeyset::PublicExponent, 4));
|
||||||
|
params.SetPrivateExponent(CryptoPP::Integer(FakeKeyset::PrivateExponent, 0x100));
|
||||||
|
|
||||||
|
params.SetModPrime1PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent1, 0x80));
|
||||||
|
params.SetModPrime2PrivateExponent(CryptoPP::Integer(FakeKeyset::Exponent2, 0x80));
|
||||||
|
|
||||||
|
params.SetModulus(CryptoPP::Integer(FakeKeyset::Modulus, 0x100));
|
||||||
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
|
CryptoPP::Integer(FakeKeyset::Coefficient, 0x80));
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey Crypto::DebugRifKeyset_init() {
|
||||||
|
CryptoPP::InvertibleRSAFunction params;
|
||||||
|
params.SetPrime1(CryptoPP::Integer(DebugRifKeyset::Prime1, sizeof(DebugRifKeyset::Prime1)));
|
||||||
|
params.SetPrime2(CryptoPP::Integer(DebugRifKeyset::Prime2, sizeof(DebugRifKeyset::Prime2)));
|
||||||
|
|
||||||
|
params.SetPublicExponent(
|
||||||
|
CryptoPP::Integer(DebugRifKeyset::PublicExponent, sizeof(DebugRifKeyset::PublicExponent)));
|
||||||
|
params.SetPrivateExponent(CryptoPP::Integer(DebugRifKeyset::PrivateExponent,
|
||||||
|
sizeof(DebugRifKeyset::PrivateExponent)));
|
||||||
|
|
||||||
|
params.SetModPrime1PrivateExponent(
|
||||||
|
CryptoPP::Integer(DebugRifKeyset::Exponent1, sizeof(DebugRifKeyset::Exponent1)));
|
||||||
|
params.SetModPrime2PrivateExponent(
|
||||||
|
CryptoPP::Integer(DebugRifKeyset::Exponent2, sizeof(DebugRifKeyset::Exponent2)));
|
||||||
|
|
||||||
|
params.SetModulus(CryptoPP::Integer(DebugRifKeyset::Modulus, sizeof(DebugRifKeyset::Modulus)));
|
||||||
|
params.SetMultiplicativeInverseOfPrime2ModPrime1(
|
||||||
|
CryptoPP::Integer(DebugRifKeyset::Coefficient, sizeof(DebugRifKeyset::Coefficient)));
|
||||||
|
|
||||||
|
CryptoPP::RSA::PrivateKey privateKey(params);
|
||||||
|
|
||||||
|
return privateKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::RSA2048Decrypt(std::span<CryptoPP::byte, 32> dec_key,
|
||||||
|
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||||
|
bool is_dk3) { // RSAES_PKCS1v15_
|
||||||
|
// Create an RSA decryptor
|
||||||
|
CryptoPP::RSA::PrivateKey privateKey;
|
||||||
|
if (is_dk3) {
|
||||||
|
privateKey = key_pkg_derived_key3_keyset_init();
|
||||||
|
} else {
|
||||||
|
privateKey = FakeKeyset_keyset_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
CryptoPP::RSAES_PKCS1v15_Decryptor rsaDecryptor(privateKey);
|
||||||
|
|
||||||
|
// Allocate memory for the decrypted data
|
||||||
|
std::array<CryptoPP::byte, 256> decrypted;
|
||||||
|
|
||||||
|
// Perform the decryption
|
||||||
|
CryptoPP::AutoSeededRandomPool rng;
|
||||||
|
CryptoPP::DecodingResult result =
|
||||||
|
rsaDecryptor.Decrypt(rng, ciphertext.data(), decrypted.size(), decrypted.data());
|
||||||
|
std::copy(decrypted.begin(), decrypted.begin() + dec_key.size(), dec_key.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::ivKeyHASH256(std::span<const CryptoPP::byte, 64> cipher_input,
|
||||||
|
std::span<CryptoPP::byte, 32> ivkey_result) {
|
||||||
|
CryptoPP::SHA256 sha256;
|
||||||
|
std::array<CryptoPP::byte, CryptoPP::SHA256::DIGESTSIZE> hashResult;
|
||||||
|
auto array_sink = new CryptoPP::ArraySink(hashResult.data(), CryptoPP::SHA256::DIGESTSIZE);
|
||||||
|
auto filter = new CryptoPP::HashFilter(sha256, array_sink);
|
||||||
|
CryptoPP::ArraySource r(cipher_input.data(), cipher_input.size(), true, filter);
|
||||||
|
std::copy(hashResult.begin(), hashResult.begin() + ivkey_result.size(), ivkey_result.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::aesCbcCfb128Decrypt(std::span<const CryptoPP::byte, 32> ivkey,
|
||||||
|
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||||
|
std::span<CryptoPP::byte, 256> decrypted) {
|
||||||
|
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> key;
|
||||||
|
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> iv;
|
||||||
|
|
||||||
|
std::copy(ivkey.begin() + 16, ivkey.begin() + 16 + key.size(), key.begin());
|
||||||
|
std::copy(ivkey.begin(), ivkey.begin() + iv.size(), iv.begin());
|
||||||
|
|
||||||
|
CryptoPP::AES::Decryption aesDecryption(key.data(), CryptoPP::AES::DEFAULT_KEYLENGTH);
|
||||||
|
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||||
|
cbcDecryption.ProcessData(decrypted.data() + i, ciphertext.data() + i,
|
||||||
|
CryptoPP::AES::BLOCKSIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
|
||||||
|
std::span<CryptoPP::byte> ciphertext,
|
||||||
|
std::span<CryptoPP::byte> decrypted) {
|
||||||
|
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> key;
|
||||||
|
std::array<CryptoPP::byte, CryptoPP::AES::DEFAULT_KEYLENGTH> iv;
|
||||||
|
|
||||||
|
std::copy(ivkey.begin() + 16, ivkey.begin() + 16 + key.size(), key.begin());
|
||||||
|
std::copy(ivkey.begin(), ivkey.begin() + iv.size(), iv.begin());
|
||||||
|
|
||||||
|
CryptoPP::AES::Decryption aesDecryption(key.data(), CryptoPP::AES::DEFAULT_KEYLENGTH);
|
||||||
|
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||||
|
cbcDecryption.ProcessData(decrypted.data() + i, ciphertext.data() + i,
|
||||||
|
CryptoPP::AES::BLOCKSIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
|
||||||
|
std::span<CryptoPP::byte, 16> NPcommID,
|
||||||
|
std::span<CryptoPP::byte, 16> efsmIv, std::span<CryptoPP::byte> ciphertext,
|
||||||
|
std::span<CryptoPP::byte> decrypted) {
|
||||||
|
|
||||||
|
// step 1: Encrypt NPcommID
|
||||||
|
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt;
|
||||||
|
|
||||||
|
std::vector<CryptoPP::byte> trophyIv(16, 0);
|
||||||
|
std::vector<CryptoPP::byte> trpKey(16);
|
||||||
|
|
||||||
|
encrypt.SetKeyWithIV(trophyKey.data(), trophyKey.size(), trophyIv.data());
|
||||||
|
encrypt.ProcessData(trpKey.data(), NPcommID.data(), 16);
|
||||||
|
|
||||||
|
// step 2: decrypt efsm.
|
||||||
|
CryptoPP::CBC_Mode<CryptoPP::AES>::Decryption decrypt;
|
||||||
|
decrypt.SetKeyWithIV(trpKey.data(), trpKey.size(), efsmIv.data());
|
||||||
|
|
||||||
|
for (size_t i = 0; i < decrypted.size(); i += CryptoPP::AES::BLOCKSIZE) {
|
||||||
|
decrypt.ProcessData(decrypted.data() + i, ciphertext.data() + i, CryptoPP::AES::BLOCKSIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::PfsGenCryptoKey(std::span<const CryptoPP::byte, 32> ekpfs,
|
||||||
|
std::span<const CryptoPP::byte, 16> seed,
|
||||||
|
std::span<CryptoPP::byte, 16> dataKey,
|
||||||
|
std::span<CryptoPP::byte, 16> tweakKey) {
|
||||||
|
CryptoPP::HMAC<CryptoPP::SHA256> hmac(ekpfs.data(), ekpfs.size());
|
||||||
|
|
||||||
|
CryptoPP::SecByteBlock d(20); // Use Crypto++ SecByteBlock for better memory management
|
||||||
|
|
||||||
|
// Copy the bytes of 'index' to the 'd' array
|
||||||
|
uint32_t index = 1;
|
||||||
|
std::memcpy(d, &index, sizeof(uint32_t));
|
||||||
|
|
||||||
|
// Copy the bytes of 'seed' to the 'd' array starting from index 4
|
||||||
|
std::memcpy(d + sizeof(uint32_t), seed.data(), seed.size());
|
||||||
|
|
||||||
|
// Allocate memory for 'u64' using new
|
||||||
|
std::vector<CryptoPP::byte> data_tweak_key(hmac.DigestSize());
|
||||||
|
|
||||||
|
// Calculate the HMAC
|
||||||
|
hmac.CalculateDigest(data_tweak_key.data(), d, d.size());
|
||||||
|
std::copy(data_tweak_key.begin(), data_tweak_key.begin() + dataKey.size(), tweakKey.begin());
|
||||||
|
std::copy(data_tweak_key.begin() + tweakKey.size(),
|
||||||
|
data_tweak_key.begin() + tweakKey.size() + dataKey.size(), dataKey.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Crypto::decryptPFS(std::span<const CryptoPP::byte, 16> dataKey,
|
||||||
|
std::span<const CryptoPP::byte, 16> tweakKey, std::span<const u8> src_image,
|
||||||
|
std::span<CryptoPP::byte> dst_image, u64 sector) {
|
||||||
|
// Start at 0x10000 to keep the header when decrypting the whole pfs_image.
|
||||||
|
for (int i = 0; i < src_image.size(); i += 0x1000) {
|
||||||
|
const u64 current_sector = sector + (i / 0x1000);
|
||||||
|
CryptoPP::ECB_Mode<CryptoPP::AES>::Encryption encrypt(tweakKey.data(), tweakKey.size());
|
||||||
|
CryptoPP::ECB_Mode<CryptoPP::AES>::Decryption decrypt(dataKey.data(), dataKey.size());
|
||||||
|
|
||||||
|
std::array<CryptoPP::byte, 16> tweak{};
|
||||||
|
std::array<CryptoPP::byte, 16> encryptedTweak;
|
||||||
|
std::array<CryptoPP::byte, 16> xorBuffer;
|
||||||
|
std::memcpy(tweak.data(), ¤t_sector, sizeof(u64));
|
||||||
|
|
||||||
|
// Encrypt the tweak for each sector.
|
||||||
|
encrypt.ProcessData(encryptedTweak.data(), tweak.data(), 16);
|
||||||
|
|
||||||
|
for (int plaintextOffset = 0; plaintextOffset < 0x1000; plaintextOffset += 16) {
|
||||||
|
xtsXorBlock(xorBuffer.data(), src_image.data() + i + plaintextOffset,
|
||||||
|
encryptedTweak.data()); // x, c, t
|
||||||
|
decrypt.ProcessData(xorBuffer.data(), xorBuffer.data(), 16); // x, x
|
||||||
|
xtsXorBlock(dst_image.data() + i + plaintextOffset, xorBuffer.data(),
|
||||||
|
encryptedTweak.data()); //(p) c, x , t
|
||||||
|
xtsMult(encryptedTweak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
src/core/crypto/crypto.h
Normal file
63
src/core/crypto/crypto.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <span>
|
||||||
|
#include <cryptopp/aes.h>
|
||||||
|
#include <cryptopp/filters.h>
|
||||||
|
#include <cryptopp/modes.h>
|
||||||
|
#include <cryptopp/oaep.h>
|
||||||
|
#include <cryptopp/osrng.h>
|
||||||
|
#include <cryptopp/rsa.h>
|
||||||
|
#include <cryptopp/sha.h>
|
||||||
|
|
||||||
|
#include "common/types.h"
|
||||||
|
#include "keys.h"
|
||||||
|
|
||||||
|
class Crypto {
|
||||||
|
public:
|
||||||
|
CryptoPP::RSA::PrivateKey key_pkg_derived_key3_keyset_init();
|
||||||
|
CryptoPP::RSA::PrivateKey FakeKeyset_keyset_init();
|
||||||
|
CryptoPP::RSA::PrivateKey DebugRifKeyset_init();
|
||||||
|
|
||||||
|
void RSA2048Decrypt(std::span<CryptoPP::byte, 32> dk3,
|
||||||
|
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||||
|
bool is_dk3); // RSAES_PKCS1v15_
|
||||||
|
void ivKeyHASH256(std::span<const CryptoPP::byte, 64> cipher_input,
|
||||||
|
std::span<CryptoPP::byte, 32> ivkey_result);
|
||||||
|
void aesCbcCfb128Decrypt(std::span<const CryptoPP::byte, 32> ivkey,
|
||||||
|
std::span<const CryptoPP::byte, 256> ciphertext,
|
||||||
|
std::span<CryptoPP::byte, 256> decrypted);
|
||||||
|
void aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
|
||||||
|
std::span<CryptoPP::byte> ciphertext,
|
||||||
|
std::span<CryptoPP::byte> decrypted);
|
||||||
|
void decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
|
||||||
|
std::span<CryptoPP::byte, 16> NPcommID, std::span<CryptoPP::byte, 16> efsmIv,
|
||||||
|
std::span<CryptoPP::byte> ciphertext, std::span<CryptoPP::byte> decrypted);
|
||||||
|
void PfsGenCryptoKey(std::span<const CryptoPP::byte, 32> ekpfs,
|
||||||
|
std::span<const CryptoPP::byte, 16> seed,
|
||||||
|
std::span<CryptoPP::byte, 16> dataKey,
|
||||||
|
std::span<CryptoPP::byte, 16> tweakKey);
|
||||||
|
void decryptPFS(std::span<const CryptoPP::byte, 16> dataKey,
|
||||||
|
std::span<const CryptoPP::byte, 16> tweakKey, std::span<const u8> src_image,
|
||||||
|
std::span<CryptoPP::byte> dst_image, u64 sector);
|
||||||
|
|
||||||
|
void xtsXorBlock(CryptoPP::byte* x, const CryptoPP::byte* a, const CryptoPP::byte* b) {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
x[i] = a[i] ^ b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void xtsMult(std::span<CryptoPP::byte, 16> encryptedTweak) {
|
||||||
|
int feedback = 0;
|
||||||
|
for (int k = 0; k < encryptedTweak.size(); k++) {
|
||||||
|
const auto tmp = (encryptedTweak[k] >> 7) & 1;
|
||||||
|
encryptedTweak[k] = ((encryptedTweak[k] << 1) + feedback) & 0xFF;
|
||||||
|
feedback = tmp;
|
||||||
|
}
|
||||||
|
if (feedback != 0) {
|
||||||
|
encryptedTweak[0] ^= 0x87;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
305
src/core/crypto/keys.h
Normal file
305
src/core/crypto/keys.h
Normal file
|
@ -0,0 +1,305 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <cryptopp/rsa.h>
|
||||||
|
|
||||||
|
class FakeKeyset {
|
||||||
|
public:
|
||||||
|
// Constructor
|
||||||
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0x6D, 0x48, 0xE0, 0x54, 0x40, 0x25, 0xC8, 0x41, 0x29, 0x52, 0x42, 0x27, 0xEB, 0xD2, 0xC7,
|
||||||
|
0xAB, 0x6B, 0x9C, 0x27, 0x0A, 0xB4, 0x1F, 0x94, 0x4E, 0xFA, 0x42, 0x1D, 0xB7, 0xBC, 0xB9,
|
||||||
|
0xAE, 0xBC, 0x04, 0x6F, 0x75, 0x8F, 0x10, 0x5F, 0x89, 0xAC, 0xAB, 0x9C, 0xD2, 0xFA, 0xE6,
|
||||||
|
0xA4, 0x13, 0x83, 0x68, 0xD4, 0x56, 0x38, 0xFE, 0xE5, 0x2B, 0x78, 0x44, 0x9C, 0x34, 0xE6,
|
||||||
|
0x5A, 0xA0, 0xBE, 0x05, 0x70, 0xAD, 0x15, 0xC3, 0x2D, 0x31, 0xAC, 0x97, 0x5D, 0x88, 0xFC,
|
||||||
|
0xC1, 0x62, 0x3D, 0xE2, 0xED, 0x11, 0xDB, 0xB6, 0x9E, 0xFC, 0x5A, 0x5A, 0x03, 0xF6, 0xCF,
|
||||||
|
0x08, 0xD4, 0x5D, 0x90, 0xC9, 0x2A, 0xB9, 0x9B, 0xCF, 0xC8, 0x1A, 0x65, 0xF3, 0x5B, 0xE8,
|
||||||
|
0x7F, 0xCF, 0xA5, 0xA6, 0x4C, 0x5C, 0x2A, 0x12, 0x0F, 0x92, 0xA5, 0xE3, 0xF0, 0x17, 0x1E,
|
||||||
|
0x9A, 0x97, 0x45, 0x86, 0xFD, 0xDB, 0x54, 0x25};
|
||||||
|
// exponent2 = d mod (q - 1)
|
||||||
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0x2A, 0x51, 0xCE, 0x02, 0x44, 0x28, 0x50, 0xE8, 0x30, 0x20, 0x7C, 0x9C, 0x55, 0xBF, 0x60,
|
||||||
|
0x39, 0xBC, 0xD1, 0xF0, 0xE7, 0x68, 0xF8, 0x08, 0x5B, 0x61, 0x1F, 0xA7, 0xBF, 0xD0, 0xE8,
|
||||||
|
0x8B, 0xB5, 0xB1, 0xD5, 0xD9, 0x16, 0xAC, 0x75, 0x0C, 0x6D, 0xF2, 0xE0, 0xB5, 0x97, 0x75,
|
||||||
|
0xD2, 0x68, 0x16, 0x1F, 0x00, 0x7D, 0x8B, 0x17, 0xE8, 0x78, 0x48, 0x41, 0x71, 0x2B, 0x18,
|
||||||
|
0x96, 0x80, 0x11, 0xDB, 0x68, 0x39, 0x9C, 0xD6, 0xE0, 0x72, 0x42, 0x86, 0xF0, 0x1B, 0x16,
|
||||||
|
0x0D, 0x3E, 0x12, 0x94, 0x3D, 0x25, 0xA8, 0xA9, 0x30, 0x9E, 0x54, 0x5A, 0xD6, 0x36, 0x6C,
|
||||||
|
0xD6, 0x8C, 0x20, 0x62, 0x8F, 0xA1, 0x6B, 0x1F, 0x7C, 0x6D, 0xB2, 0xB1, 0xC1, 0x2E, 0xAD,
|
||||||
|
0x36, 0x02, 0x9C, 0x3A, 0xCA, 0x2F, 0x09, 0xD2, 0x45, 0x9E, 0xEB, 0xF2, 0xBC, 0x6C, 0xAA,
|
||||||
|
0x3B, 0x3E, 0x90, 0xBC, 0x38, 0x67, 0x35, 0x4D};
|
||||||
|
// e
|
||||||
|
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||||
|
// (InverseQ)(q) = 1 mod p
|
||||||
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0x0B, 0x67, 0x1C, 0x0D, 0x6C, 0x57, 0xD3, 0xE7, 0x05, 0x65, 0x94, 0x31, 0x56, 0x55, 0xFD,
|
||||||
|
0x28, 0x08, 0xFA, 0x05, 0x8A, 0xCC, 0x55, 0x39, 0x61, 0x97, 0x63, 0xA0, 0x16, 0x27, 0x3D,
|
||||||
|
0xED, 0xC1, 0x16, 0x40, 0x2A, 0x12, 0xEA, 0x6F, 0xD9, 0xD8, 0x58, 0x56, 0xA8, 0x56, 0x8B,
|
||||||
|
0x0D, 0x38, 0x5E, 0x1E, 0x80, 0x3B, 0x5F, 0x40, 0x80, 0x6F, 0x62, 0x4F, 0x28, 0xA2, 0x69,
|
||||||
|
0xF3, 0xD3, 0xF7, 0xFD, 0xB2, 0xC3, 0x52, 0x43, 0x20, 0x92, 0x9D, 0x97, 0x8D, 0xA0, 0x15,
|
||||||
|
0x07, 0x15, 0x6E, 0xA4, 0x0D, 0x56, 0xD3, 0x37, 0x1A, 0xC4, 0x9E, 0xDF, 0x02, 0x49, 0xB8,
|
||||||
|
0x0A, 0x84, 0x62, 0xF5, 0xFA, 0xB9, 0x3F, 0xA4, 0x09, 0x76, 0xCC, 0xAA, 0xB9, 0x9B, 0xA6,
|
||||||
|
0x4F, 0xC1, 0x6A, 0x64, 0xCE, 0xD8, 0x77, 0xAB, 0x4B, 0xF9, 0xA0, 0xAE, 0xDA, 0xF1, 0x67,
|
||||||
|
0x87, 0x7C, 0x98, 0x5C, 0x7E, 0xB8, 0x73, 0xF5};
|
||||||
|
// n = p * q
|
||||||
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xC6, 0xCF, 0x71, 0xE7, 0xE5, 0x9A, 0xF0, 0xD1, 0x2A, 0x2C, 0x45, 0x8B, 0xF9, 0x2A, 0x0E,
|
||||||
|
0xC1, 0x43, 0x05, 0x8B, 0xC3, 0x71, 0x17, 0x80, 0x1D, 0xCD, 0x49, 0x7D, 0xDE, 0x35, 0x9D,
|
||||||
|
0x25, 0x9B, 0xA0, 0xD7, 0xA0, 0xF2, 0x7D, 0x6C, 0x08, 0x7E, 0xAA, 0x55, 0x02, 0x68, 0x2B,
|
||||||
|
0x23, 0xC6, 0x44, 0xB8, 0x44, 0x18, 0xEB, 0x56, 0xCF, 0x16, 0xA2, 0x48, 0x03, 0xC9, 0xE7,
|
||||||
|
0x4F, 0x87, 0xEB, 0x3D, 0x30, 0xC3, 0x15, 0x88, 0xBF, 0x20, 0xE7, 0x9D, 0xFF, 0x77, 0x0C,
|
||||||
|
0xDE, 0x1D, 0x24, 0x1E, 0x63, 0xA9, 0x4F, 0x8A, 0xBF, 0x5B, 0xBE, 0x60, 0x19, 0x68, 0x33,
|
||||||
|
0x3B, 0xFC, 0xED, 0x9F, 0x47, 0x4E, 0x5F, 0xF8, 0xEA, 0xCB, 0x3D, 0x00, 0xBD, 0x67, 0x01,
|
||||||
|
0xF9, 0x2C, 0x6D, 0xC6, 0xAC, 0x13, 0x64, 0xE7, 0x67, 0x14, 0xF3, 0xDC, 0x52, 0x69, 0x6A,
|
||||||
|
0xB9, 0x83, 0x2C, 0x42, 0x30, 0x13, 0x1B, 0xB2, 0xD8, 0xA5, 0x02, 0x0D, 0x79, 0xED, 0x96,
|
||||||
|
0xB1, 0x0D, 0xF8, 0xCC, 0x0C, 0xDF, 0x81, 0x95, 0x4F, 0x03, 0x58, 0x09, 0x57, 0x0E, 0x80,
|
||||||
|
0x69, 0x2E, 0xFE, 0xFF, 0x52, 0x77, 0xEA, 0x75, 0x28, 0xA8, 0xFB, 0xC9, 0xBE, 0xBF, 0x9F,
|
||||||
|
0xBB, 0xB7, 0x79, 0x8E, 0x18, 0x05, 0xE1, 0x80, 0xBD, 0x50, 0x34, 0x94, 0x81, 0xD3, 0x53,
|
||||||
|
0xC2, 0x69, 0xA2, 0xD2, 0x4C, 0xCF, 0x6C, 0xF4, 0x57, 0x2C, 0x10, 0x4A, 0x3F, 0xFB, 0x22,
|
||||||
|
0xFD, 0x8B, 0x97, 0xE2, 0xC9, 0x5B, 0xA6, 0x2B, 0xCD, 0xD6, 0x1B, 0x6B, 0xDB, 0x68, 0x7F,
|
||||||
|
0x4B, 0xC2, 0xA0, 0x50, 0x34, 0xC0, 0x05, 0xE5, 0x8D, 0xEF, 0x24, 0x67, 0xFF, 0x93, 0x40,
|
||||||
|
0xCF, 0x2D, 0x62, 0xA2, 0xA0, 0x50, 0xB1, 0xF1, 0x3A, 0xA8, 0x3D, 0xFD, 0x80, 0xD1, 0xF9,
|
||||||
|
0xB8, 0x05, 0x22, 0xAF, 0xC8, 0x35, 0x45, 0x90, 0x58, 0x8E, 0xE3, 0x3A, 0x7C, 0xBD, 0x3E,
|
||||||
|
0x27};
|
||||||
|
// p
|
||||||
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xFE, 0xF6, 0xBF, 0x1D, 0x69, 0xAB, 0x16, 0x25, 0x08, 0x47, 0x55, 0x6B, 0x86, 0xE4, 0x35,
|
||||||
|
0x88, 0x72, 0x2A, 0xB1, 0x3D, 0xF8, 0xB6, 0x44, 0xCA, 0xB3, 0xAB, 0x19, 0xD1, 0x04, 0x24,
|
||||||
|
0x28, 0x0A, 0x74, 0x55, 0xB8, 0x15, 0x45, 0x09, 0xCC, 0x13, 0x1C, 0xF2, 0xBA, 0x37, 0xA9,
|
||||||
|
0x03, 0x90, 0x8F, 0x02, 0x10, 0xFF, 0x25, 0x79, 0x86, 0xCC, 0x18, 0x50, 0x9A, 0x10, 0x5F,
|
||||||
|
0x5B, 0x4C, 0x1C, 0x4E, 0xB0, 0xA7, 0xE3, 0x59, 0xB1, 0x2D, 0xA0, 0xC6, 0xB0, 0x20, 0x2C,
|
||||||
|
0x21, 0x33, 0x12, 0xB3, 0xAF, 0x72, 0x34, 0x83, 0xCD, 0x52, 0x2F, 0xAF, 0x0F, 0x20, 0x5A,
|
||||||
|
0x1B, 0xC0, 0xE2, 0xA3, 0x76, 0x34, 0x0F, 0xD7, 0xFC, 0xC1, 0x41, 0xC9, 0xF9, 0x79, 0x40,
|
||||||
|
0x17, 0x42, 0x21, 0x3E, 0x9D, 0xFD, 0xC7, 0xC1, 0x50, 0xDE, 0x44, 0x5A, 0xC9, 0x31, 0x89,
|
||||||
|
0x6A, 0x78, 0x05, 0xBE, 0x65, 0xB4, 0xE8, 0x2D};
|
||||||
|
// q
|
||||||
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
|
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};
|
||||||
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
|
0x7F, 0x76, 0xCD, 0x0E, 0xE2, 0xD4, 0xDE, 0x05, 0x1C, 0xC6, 0xD9, 0xA8, 0x0E, 0x8D, 0xFA,
|
||||||
|
0x7B, 0xCA, 0x1E, 0xAA, 0x27, 0x1A, 0x40, 0xF8, 0xF1, 0x22, 0x87, 0x35, 0xDD, 0xDB, 0xFD,
|
||||||
|
0xEE, 0xF8, 0xC2, 0xBC, 0xBD, 0x01, 0xFB, 0x8B, 0xE2, 0x3E, 0x63, 0xB2, 0xB1, 0x22, 0x5C,
|
||||||
|
0x56, 0x49, 0x6E, 0x11, 0xBE, 0x07, 0x44, 0x0B, 0x9A, 0x26, 0x66, 0xD1, 0x49, 0x2C, 0x8F,
|
||||||
|
0xD3, 0x1B, 0xCF, 0xA4, 0xA1, 0xB8, 0xD1, 0xFB, 0xA4, 0x9E, 0xD2, 0x21, 0x28, 0x83, 0x09,
|
||||||
|
0x8A, 0xF6, 0xA0, 0x0B, 0xA3, 0xD6, 0x0F, 0x9B, 0x63, 0x68, 0xCC, 0xBC, 0x0C, 0x4E, 0x14,
|
||||||
|
0x5B, 0x27, 0xA4, 0xA9, 0xF4, 0x2B, 0xB9, 0xB8, 0x7B, 0xC0, 0xE6, 0x51, 0xAD, 0x1D, 0x77,
|
||||||
|
0xD4, 0x6B, 0xB9, 0xCE, 0x20, 0xD1, 0x26, 0x66, 0x7E, 0x5E, 0x9E, 0xA2, 0xE9, 0x6B, 0x90,
|
||||||
|
0xF3, 0x73, 0xB8, 0x52, 0x8F, 0x44, 0x11, 0x03, 0x0C, 0x13, 0x97, 0x39, 0x3D, 0x13, 0x22,
|
||||||
|
0x58, 0xD5, 0x43, 0x82, 0x49, 0xDA, 0x6E, 0x7C, 0xA1, 0xC5, 0x8C, 0xA5, 0xB0, 0x09, 0xE0,
|
||||||
|
0xCE, 0x3D, 0xDF, 0xF4, 0x9D, 0x3C, 0x97, 0x15, 0xE2, 0x6A, 0xC7, 0x2B, 0x3C, 0x50, 0x93,
|
||||||
|
0x23, 0xDB, 0xBA, 0x4A, 0x22, 0x66, 0x44, 0xAC, 0x78, 0xBB, 0x0E, 0x1A, 0x27, 0x43, 0xB5,
|
||||||
|
0x71, 0x67, 0xAF, 0xF4, 0xAB, 0x48, 0x46, 0x93, 0x73, 0xD0, 0x42, 0xAB, 0x93, 0x63, 0xE5,
|
||||||
|
0x6C, 0x9A, 0xDE, 0x50, 0x24, 0xC0, 0x23, 0x7D, 0x99, 0x79, 0x3F, 0x22, 0x07, 0xE0, 0xC1,
|
||||||
|
0x48, 0x56, 0x1B, 0xDF, 0x83, 0x09, 0x12, 0xB4, 0x2D, 0x45, 0x6B, 0xC9, 0xC0, 0x68, 0x85,
|
||||||
|
0x99, 0x90, 0x79, 0x96, 0x1A, 0xD7, 0xF5, 0x4D, 0x1F, 0x37, 0x83, 0x40, 0x4A, 0xEC, 0x39,
|
||||||
|
0x37, 0xA6, 0x80, 0x92, 0x7D, 0xC5, 0x80, 0xC7, 0xD6, 0x6F, 0xFE, 0x8A, 0x79, 0x89, 0xC6,
|
||||||
|
0xB1};
|
||||||
|
};
|
||||||
|
|
||||||
|
class DebugRifKeyset {
|
||||||
|
public:
|
||||||
|
// std::uint8_t* PrivateExponent;
|
||||||
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0xCD, 0x9A, 0x61, 0xB0, 0xB8, 0xD5, 0xB4, 0xE4, 0xE4, 0xF6, 0xAB, 0xF7, 0x27, 0xB7, 0x56,
|
||||||
|
0x59, 0x6B, 0xB9, 0x11, 0xE7, 0xF4, 0x83, 0xAF, 0xB9, 0x73, 0x99, 0x7F, 0x49, 0xA2, 0x9C,
|
||||||
|
0xF0, 0xB5, 0x6D, 0x37, 0x82, 0x14, 0x15, 0xF1, 0x04, 0x8A, 0xD4, 0x8E, 0xEB, 0x2E, 0x1F,
|
||||||
|
0xE2, 0x81, 0xA9, 0x62, 0x6E, 0xB1, 0x68, 0x75, 0x62, 0xF3, 0x0F, 0xFE, 0xD4, 0x91, 0x87,
|
||||||
|
0x98, 0x78, 0xBF, 0x26, 0xB5, 0x07, 0x58, 0xD0, 0xEE, 0x3F, 0x21, 0xE8, 0xC8, 0x0F, 0x5F,
|
||||||
|
0xFA, 0x1C, 0x64, 0x74, 0x49, 0x52, 0xEB, 0xE7, 0xEE, 0xDE, 0xBA, 0x23, 0x26, 0x4A, 0xF6,
|
||||||
|
0x9C, 0x1A, 0x09, 0x3F, 0xB9, 0x0B, 0x36, 0x26, 0x1A, 0xBE, 0xA9, 0x76, 0xE6, 0xF2, 0x69,
|
||||||
|
0xDE, 0xFF, 0xAF, 0xCC, 0x0C, 0x9A, 0x66, 0x03, 0x86, 0x0A, 0x1F, 0x49, 0xA4, 0x10, 0xB6,
|
||||||
|
0xBC, 0xC3, 0x7C, 0x88, 0xE8, 0xCE, 0x4B, 0xD9};
|
||||||
|
// exponent2 = d mod (q - 1)
|
||||||
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0xB3, 0x73, 0xA3, 0x59, 0xE6, 0x97, 0xC0, 0xAB, 0x3B, 0x68, 0xFC, 0x39, 0xAC, 0xDB, 0x44,
|
||||||
|
0xB1, 0xB4, 0x9E, 0x35, 0x4D, 0xBE, 0xC5, 0x36, 0x69, 0x6C, 0x3D, 0xC5, 0xFC, 0xFE, 0x4B,
|
||||||
|
0x2F, 0xDC, 0x86, 0x80, 0x46, 0x96, 0x40, 0x1A, 0x0D, 0x6E, 0xFA, 0x8C, 0xE0, 0x47, 0x91,
|
||||||
|
0xAC, 0xAD, 0x95, 0x2B, 0x8E, 0x1F, 0xF2, 0x0A, 0x45, 0xF8, 0x29, 0x95, 0x70, 0xC6, 0x88,
|
||||||
|
0x5F, 0x71, 0x03, 0x99, 0x79, 0xBC, 0x84, 0x71, 0xBD, 0xE8, 0x84, 0x8C, 0x0E, 0xD4, 0x7B,
|
||||||
|
0x30, 0x74, 0x57, 0x1A, 0x95, 0xE7, 0x90, 0x19, 0x8D, 0xAD, 0x8B, 0x4C, 0x4E, 0xC3, 0xE7,
|
||||||
|
0x6B, 0x23, 0x86, 0x01, 0xEE, 0x9B, 0xE0, 0x2F, 0x15, 0xA2, 0x2C, 0x4C, 0x39, 0xD3, 0xDF,
|
||||||
|
0x9C, 0x39, 0x01, 0xF1, 0x8C, 0x44, 0x4A, 0x15, 0x44, 0xDC, 0x51, 0xF7, 0x22, 0xD7, 0x7F,
|
||||||
|
0x41, 0x7F, 0x68, 0xFA, 0xEE, 0x56, 0xE8, 0x05};
|
||||||
|
// e
|
||||||
|
static constexpr CryptoPP::byte PublicExponent[] = {0x00, 0x01, 0x00, 0x01};
|
||||||
|
// (InverseQ)(q) = 1 mod p
|
||||||
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0xC0, 0x32, 0x43, 0xD3, 0x8C, 0x3D, 0xB4, 0xD2, 0x48, 0x8C, 0x42, 0x41, 0x24, 0x94, 0x6C,
|
||||||
|
0x80, 0xC9, 0xC1, 0x79, 0x36, 0x7F, 0xAC, 0xC3, 0xFF, 0x6A, 0x25, 0xEB, 0x2C, 0xFB, 0xD4,
|
||||||
|
0x2B, 0xA0, 0xEB, 0xFE, 0x25, 0xE9, 0xC6, 0x77, 0xCE, 0xFE, 0x2D, 0x23, 0xFE, 0xD0, 0xF4,
|
||||||
|
0x0F, 0xD9, 0x7E, 0xD5, 0xA5, 0x7D, 0x1F, 0xC0, 0xE8, 0xE8, 0xEC, 0x80, 0x5B, 0xC7, 0xFD,
|
||||||
|
0xE2, 0xBD, 0x94, 0xA6, 0x2B, 0xDD, 0x6A, 0x60, 0x45, 0x54, 0xAB, 0xCA, 0x42, 0x9C, 0x6A,
|
||||||
|
0x6C, 0xBF, 0x3C, 0x84, 0xF9, 0xA5, 0x0E, 0x63, 0x0C, 0x51, 0x58, 0x62, 0x6D, 0x5A, 0xB7,
|
||||||
|
0x3C, 0x3F, 0x49, 0x1A, 0xD0, 0x93, 0xB8, 0x4F, 0x1A, 0x6C, 0x5F, 0xC5, 0xE5, 0xA9, 0x75,
|
||||||
|
0xD4, 0x86, 0x9E, 0xDF, 0x87, 0x0F, 0x27, 0xB0, 0x26, 0x78, 0x4E, 0xFB, 0xC1, 0x8A, 0x4A,
|
||||||
|
0x24, 0x3F, 0x7F, 0x8F, 0x9A, 0x12, 0x51, 0xCB};
|
||||||
|
// n = p * q
|
||||||
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xC2, 0xD2, 0x44, 0xBC, 0xDD, 0x84, 0x3F, 0xD9, 0xC5, 0x22, 0xAF, 0xF7, 0xFC, 0x88, 0x8A,
|
||||||
|
0x33, 0x80, 0xED, 0x8E, 0xE2, 0xCC, 0x81, 0xF7, 0xEC, 0xF8, 0x1C, 0x79, 0xBF, 0x02, 0xBB,
|
||||||
|
0x12, 0x8E, 0x61, 0x68, 0x29, 0x1B, 0x15, 0xB6, 0x5E, 0xC6, 0xF8, 0xBF, 0x5A, 0xE0, 0x3B,
|
||||||
|
0x6A, 0x6C, 0xD9, 0xD6, 0xF5, 0x75, 0xAB, 0xA0, 0x6F, 0x34, 0x81, 0x34, 0x9A, 0x5B, 0xAD,
|
||||||
|
0xED, 0x31, 0xE3, 0xC6, 0xEA, 0x1A, 0xD1, 0x13, 0x22, 0xBB, 0xB3, 0xDA, 0xB3, 0xB2, 0x53,
|
||||||
|
0xBD, 0x45, 0x79, 0x87, 0xAD, 0x0A, 0x01, 0x72, 0x18, 0x10, 0x29, 0x49, 0xF4, 0x41, 0x7F,
|
||||||
|
0xD6, 0x47, 0x0C, 0x72, 0x92, 0x9E, 0xE9, 0xBB, 0x95, 0xA9, 0x5D, 0x79, 0xEB, 0xE4, 0x30,
|
||||||
|
0x76, 0x90, 0x45, 0x4B, 0x9D, 0x9C, 0xCF, 0x92, 0x03, 0x60, 0x8C, 0x4B, 0x6C, 0xB3, 0x7A,
|
||||||
|
0x3A, 0x05, 0x39, 0xA0, 0x66, 0xA9, 0x35, 0xCF, 0xB9, 0xFA, 0xAD, 0x9C, 0xAB, 0xEB, 0xE4,
|
||||||
|
0x6A, 0x8C, 0xE9, 0x3B, 0xCC, 0x72, 0x12, 0x62, 0x63, 0xBD, 0x80, 0xC4, 0xEE, 0x37, 0x2B,
|
||||||
|
0x32, 0x03, 0xA3, 0x09, 0xF7, 0xA0, 0x61, 0x57, 0xAD, 0x0D, 0xCF, 0x15, 0x98, 0x9E, 0x4E,
|
||||||
|
0x49, 0xF8, 0xB5, 0xA3, 0x5C, 0x27, 0xEE, 0x45, 0x04, 0xEA, 0xE4, 0x4B, 0xBC, 0x8F, 0x87,
|
||||||
|
0xED, 0x19, 0x1E, 0x46, 0x75, 0x63, 0xC4, 0x5B, 0xD5, 0xBC, 0x09, 0x2F, 0x02, 0x73, 0x19,
|
||||||
|
0x3C, 0x58, 0x55, 0x49, 0x66, 0x4C, 0x11, 0xEC, 0x0F, 0x09, 0xFA, 0xA5, 0x56, 0x0A, 0x5A,
|
||||||
|
0x63, 0x56, 0xAD, 0xA0, 0x0D, 0x86, 0x08, 0xC1, 0xE6, 0xB6, 0x13, 0x22, 0x49, 0x2F, 0x7C,
|
||||||
|
0xDB, 0x4C, 0x56, 0x97, 0x0E, 0xC2, 0xD9, 0x2E, 0x87, 0xBC, 0x0E, 0x67, 0xC0, 0x1B, 0x58,
|
||||||
|
0xBC, 0x64, 0x2B, 0xC2, 0x6E, 0xE2, 0x93, 0x2E, 0xB5, 0x6B, 0x70, 0xA4, 0x42, 0x9F, 0x64,
|
||||||
|
0xC1};
|
||||||
|
// p
|
||||||
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xE5, 0x62, 0xE1, 0x7F, 0x9F, 0x86, 0x08, 0xE2, 0x61, 0xD3, 0xD0, 0x42, 0xE2, 0xC4, 0xB6,
|
||||||
|
0xA8, 0x51, 0x09, 0x19, 0x14, 0xA4, 0x3A, 0x11, 0x4C, 0x33, 0xA5, 0x9C, 0x01, 0x5E, 0x34,
|
||||||
|
0xB6, 0x3F, 0x02, 0x1A, 0xCA, 0x47, 0xF1, 0x4F, 0x3B, 0x35, 0x2A, 0x07, 0x20, 0xEC, 0xD8,
|
||||||
|
0xC1, 0x15, 0xD9, 0xCA, 0x03, 0x4F, 0xB8, 0xE8, 0x09, 0x73, 0x3F, 0x85, 0xB7, 0x41, 0xD5,
|
||||||
|
0x51, 0x3E, 0x7B, 0xE3, 0x53, 0x2B, 0x48, 0x8B, 0x8E, 0xCB, 0xBA, 0xF7, 0xE0, 0x60, 0xF5,
|
||||||
|
0x35, 0x0E, 0x6F, 0xB0, 0xD9, 0x2A, 0x99, 0xD0, 0xFF, 0x60, 0x14, 0xED, 0x40, 0xEA, 0xF8,
|
||||||
|
0xD7, 0x0B, 0xC3, 0x8D, 0x8C, 0xE8, 0x81, 0xB3, 0x75, 0x93, 0x15, 0xB3, 0x7D, 0xF6, 0x39,
|
||||||
|
0x60, 0x1A, 0x00, 0xE7, 0xC3, 0x27, 0xAD, 0xA4, 0x33, 0xD5, 0x3E, 0xA4, 0x35, 0x48, 0x6F,
|
||||||
|
0x22, 0xEF, 0x5D, 0xDD, 0x7D, 0x7B, 0x61, 0x05};
|
||||||
|
// q
|
||||||
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
|
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};
|
||||||
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
|
0x01, 0x61, 0xAD, 0xD8, 0x9C, 0x06, 0x89, 0xD0, 0x60, 0xC8, 0x41, 0xF0, 0xB3, 0x83, 0x01,
|
||||||
|
0x5D, 0xE3, 0xA2, 0x6B, 0xA2, 0xBA, 0x9A, 0x0A, 0x58, 0xCD, 0x1A, 0xA0, 0x97, 0x64, 0xEC,
|
||||||
|
0xD0, 0x31, 0x1F, 0xCA, 0x36, 0x0E, 0x69, 0xDD, 0x40, 0xF7, 0x4E, 0xC0, 0xC6, 0xA3, 0x73,
|
||||||
|
0xF0, 0x69, 0x84, 0xB2, 0xF4, 0x4B, 0x29, 0x14, 0x2A, 0x6D, 0xB8, 0x23, 0xD8, 0x1B, 0x61,
|
||||||
|
0xD4, 0x9E, 0x87, 0xB3, 0xBB, 0xA9, 0xC4, 0x85, 0x4A, 0xF8, 0x03, 0x4A, 0xBF, 0xFE, 0xF9,
|
||||||
|
0xFE, 0x8B, 0xDD, 0x54, 0x83, 0xBA, 0xE0, 0x2F, 0x3F, 0xB1, 0xEF, 0xA5, 0x05, 0x5D, 0x28,
|
||||||
|
0x8B, 0xAB, 0xB5, 0xD0, 0x23, 0x2F, 0x8A, 0xCF, 0x48, 0x7C, 0xAA, 0xBB, 0xC8, 0x5B, 0x36,
|
||||||
|
0x27, 0xC5, 0x16, 0xA4, 0xB6, 0x61, 0xAC, 0x0C, 0x28, 0x47, 0x79, 0x3F, 0x38, 0xAE, 0x5E,
|
||||||
|
0x25, 0xC6, 0xAF, 0x35, 0xAE, 0xBC, 0xB0, 0xF3, 0xBC, 0xBD, 0xFD, 0xA4, 0x87, 0x0D, 0x14,
|
||||||
|
0x3D, 0x90, 0xE4, 0xDE, 0x5D, 0x1D, 0x46, 0x81, 0xF1, 0x28, 0x6D, 0x2F, 0x2C, 0x5E, 0x97,
|
||||||
|
0x2D, 0x89, 0x2A, 0x51, 0x72, 0x3C, 0x20, 0x02, 0x59, 0xB1, 0x98, 0x93, 0x05, 0x1E, 0x3F,
|
||||||
|
0xA1, 0x8A, 0x69, 0x30, 0x0E, 0x70, 0x84, 0x8B, 0xAE, 0x97, 0xA1, 0x08, 0x95, 0x63, 0x4C,
|
||||||
|
0xC7, 0xE8, 0x5D, 0x59, 0xCA, 0x78, 0x2A, 0x23, 0x87, 0xAC, 0x6F, 0x04, 0x33, 0xB1, 0x61,
|
||||||
|
0xB9, 0xF0, 0x95, 0xDA, 0x33, 0xCC, 0xE0, 0x4C, 0x82, 0x68, 0x82, 0x14, 0x51, 0xBE, 0x49,
|
||||||
|
0x1C, 0x58, 0xA2, 0x8B, 0x05, 0x4E, 0x98, 0x37, 0xEB, 0x94, 0x0B, 0x01, 0x22, 0xDC, 0xB3,
|
||||||
|
0x19, 0xCA, 0x77, 0xA6, 0x6E, 0x97, 0xFF, 0x8A, 0x53, 0x5A, 0xC5, 0x24, 0xE4, 0xAF, 0x6E,
|
||||||
|
0xA8, 0x2B, 0x53, 0xA4, 0xBE, 0x96, 0xA5, 0x7B, 0xCE, 0x22, 0x56, 0xA3, 0xF1, 0xCF, 0x14,
|
||||||
|
0xA5};
|
||||||
|
};
|
||||||
|
|
||||||
|
class PkgDerivedKey3Keyset {
|
||||||
|
public:
|
||||||
|
// std::uint8_t* PrivateExponent;
|
||||||
|
static constexpr CryptoPP::byte Exponent1[] = {
|
||||||
|
0x52, 0xCC, 0x2D, 0xA0, 0x9C, 0x9E, 0x75, 0xE7, 0x28, 0xEE, 0x3D, 0xDE, 0xE3, 0x45, 0xD1,
|
||||||
|
0x4F, 0x94, 0x1C, 0xCC, 0xC8, 0x87, 0x29, 0x45, 0x3B, 0x8D, 0x6E, 0xAB, 0x6E, 0x2A, 0xA7,
|
||||||
|
0xC7, 0x15, 0x43, 0xA3, 0x04, 0x8F, 0x90, 0x5F, 0xEB, 0xF3, 0x38, 0x4A, 0x77, 0xFA, 0x36,
|
||||||
|
0xB7, 0x15, 0x76, 0xB6, 0x01, 0x1A, 0x8E, 0x25, 0x87, 0x82, 0xF1, 0x55, 0xD8, 0xC6, 0x43,
|
||||||
|
0x2A, 0xC0, 0xE5, 0x98, 0xC9, 0x32, 0xD1, 0x94, 0x6F, 0xD9, 0x01, 0xBA, 0x06, 0x81, 0xE0,
|
||||||
|
0x6D, 0x88, 0xF2, 0x24, 0x2A, 0x25, 0x01, 0x64, 0x5C, 0xBF, 0xF2, 0xD9, 0x99, 0x67, 0x3E,
|
||||||
|
0xF6, 0x72, 0xEE, 0xE4, 0xE2, 0x33, 0x5C, 0xF8, 0x00, 0x40, 0xE3, 0x2A, 0x9A, 0xF4, 0x3D,
|
||||||
|
0x22, 0x86, 0x44, 0x3C, 0xFB, 0x0A, 0xA5, 0x7C, 0x3F, 0xCC, 0xF5, 0xF1, 0x16, 0xC4, 0xAC,
|
||||||
|
0x88, 0xB4, 0xDE, 0x62, 0x94, 0x92, 0x6A, 0x13};
|
||||||
|
// exponent2 = d mod (q - 1)
|
||||||
|
static constexpr CryptoPP::byte Exponent2[] = {
|
||||||
|
0x7C, 0x9D, 0xAD, 0x39, 0xE0, 0xD5, 0x60, 0x14, 0x94, 0x48, 0x19, 0x7F, 0x88, 0x95, 0xD5,
|
||||||
|
0x8B, 0x80, 0xAD, 0x85, 0x8A, 0x4B, 0x77, 0x37, 0x85, 0xD0, 0x77, 0xBB, 0xBF, 0x89, 0x71,
|
||||||
|
0x4A, 0x72, 0xCB, 0x72, 0x68, 0x38, 0xEC, 0x02, 0xC6, 0x7D, 0xC6, 0x44, 0x06, 0x33, 0x51,
|
||||||
|
0x1C, 0xC0, 0xFF, 0x95, 0x8F, 0x0D, 0x75, 0xDC, 0x25, 0xBB, 0x0B, 0x73, 0x91, 0xA9, 0x6D,
|
||||||
|
0x42, 0xD8, 0x03, 0xB7, 0x68, 0xD4, 0x1E, 0x75, 0x62, 0xA3, 0x70, 0x35, 0x79, 0x78, 0x00,
|
||||||
|
0xC8, 0xF5, 0xEF, 0x15, 0xB9, 0xFC, 0x4E, 0x47, 0x5A, 0xC8, 0x70, 0x70, 0x5B, 0x52, 0x98,
|
||||||
|
0xC0, 0xC2, 0x58, 0x4A, 0x70, 0x96, 0xCC, 0xB8, 0x10, 0xE1, 0x2F, 0x78, 0x8B, 0x2B, 0xA1,
|
||||||
|
0x7F, 0xF9, 0xAC, 0xDE, 0xF0, 0xBB, 0x2B, 0xE2, 0x66, 0xE3, 0x22, 0x92, 0x31, 0x21, 0x57,
|
||||||
|
0x92, 0xC4, 0xB8, 0xF2, 0x3E, 0x76, 0x20, 0x37};
|
||||||
|
// e
|
||||||
|
static constexpr CryptoPP::byte PublicExponent[] = {0, 1, 0, 1};
|
||||||
|
// (InverseQ)(q) = 1 mod p
|
||||||
|
static constexpr CryptoPP::byte Coefficient[] = {
|
||||||
|
0x45, 0x97, 0x55, 0xD4, 0x22, 0x08, 0x5E, 0xF3, 0x5C, 0xB4, 0x05, 0x7A, 0xFD, 0xAA, 0x42,
|
||||||
|
0x42, 0xAD, 0x9A, 0x8C, 0xA0, 0x6C, 0xBB, 0x1D, 0x68, 0x54, 0x54, 0x6E, 0x3E, 0x32, 0xE3,
|
||||||
|
0x53, 0x73, 0x76, 0xF1, 0x3E, 0x01, 0xEA, 0xD3, 0xCF, 0xEB, 0xEB, 0x23, 0x3E, 0xC0, 0xBE,
|
||||||
|
0xCE, 0xEC, 0x2C, 0x89, 0x5F, 0xA8, 0x27, 0x3A, 0x4C, 0xB7, 0xE6, 0x74, 0xBC, 0x45, 0x4C,
|
||||||
|
0x26, 0xC8, 0x25, 0xFF, 0x34, 0x63, 0x25, 0x37, 0xE1, 0x48, 0x10, 0xC1, 0x93, 0xA6, 0xAF,
|
||||||
|
0xEB, 0xBA, 0xE3, 0xA2, 0xF1, 0x3D, 0xEF, 0x63, 0xD8, 0xF4, 0xFD, 0xD3, 0xEE, 0xE2, 0x5D,
|
||||||
|
0xE9, 0x33, 0xCC, 0xAD, 0xBA, 0x75, 0x5C, 0x85, 0xAF, 0xCE, 0xA9, 0x3D, 0xD1, 0xA2, 0x17,
|
||||||
|
0xF3, 0xF6, 0x98, 0xB3, 0x50, 0x8E, 0x5E, 0xF6, 0xEB, 0x02, 0x8E, 0xA1, 0x62, 0xA7, 0xD6,
|
||||||
|
0x2C, 0xEC, 0x91, 0xFF, 0x15, 0x40, 0xD2, 0xE3};
|
||||||
|
// n = p * q
|
||||||
|
static constexpr CryptoPP::byte Modulus[] = {
|
||||||
|
0xd2, 0x12, 0xfc, 0x33, 0x5f, 0x6d, 0xdb, 0x83, 0x16, 0x09, 0x62, 0x8b, 0x03, 0x56, 0x27,
|
||||||
|
0x37, 0x82, 0xd4, 0x77, 0x85, 0x35, 0x29, 0x39, 0x2d, 0x52, 0x6b, 0x8c, 0x4c, 0x8c, 0xfb,
|
||||||
|
0x06, 0xc1, 0x84, 0x5b, 0xe7, 0xd4, 0xf7, 0xbc, 0xd2, 0x4e, 0x62, 0x45, 0xcd, 0x2a, 0xbb,
|
||||||
|
0xd7, 0x77, 0x76, 0x45, 0x36, 0x55, 0x27, 0x3f, 0xb3, 0xf5, 0xf9, 0x8e, 0xda, 0x4b, 0xef,
|
||||||
|
0xaa, 0x59, 0xae, 0xb3, 0x9b, 0xea, 0x54, 0x98, 0xd2, 0x06, 0x32, 0x6a, 0x58, 0x31, 0x2a,
|
||||||
|
0xe0, 0xd4, 0x4f, 0x90, 0xb5, 0x0a, 0x7d, 0xec, 0xf4, 0x3a, 0x9c, 0x52, 0x67, 0x2d, 0x99,
|
||||||
|
0x31, 0x8e, 0x0c, 0x43, 0xe6, 0x82, 0xfe, 0x07, 0x46, 0xe1, 0x2e, 0x50, 0xd4, 0x1f, 0x2d,
|
||||||
|
0x2f, 0x7e, 0xd9, 0x08, 0xba, 0x06, 0xb3, 0xbf, 0x2e, 0x20, 0x3f, 0x4e, 0x3f, 0xfe, 0x44,
|
||||||
|
0xff, 0xaa, 0x50, 0x43, 0x57, 0x91, 0x69, 0x94, 0x49, 0x15, 0x82, 0x82, 0xe4, 0x0f, 0x4c,
|
||||||
|
0x8d, 0x9d, 0x2c, 0xc9, 0x5b, 0x1d, 0x64, 0xbf, 0x88, 0x8b, 0xd4, 0xc5, 0x94, 0xe7, 0x65,
|
||||||
|
0x47, 0x84, 0x1e, 0xe5, 0x79, 0x10, 0xfb, 0x98, 0x93, 0x47, 0xb9, 0x7d, 0x85, 0x12, 0xa6,
|
||||||
|
0x40, 0x98, 0x2c, 0xf7, 0x92, 0xbc, 0x95, 0x19, 0x32, 0xed, 0xe8, 0x90, 0x56, 0x0d, 0x65,
|
||||||
|
0xc1, 0xaa, 0x78, 0xc6, 0x2e, 0x54, 0xfd, 0x5f, 0x54, 0xa1, 0xf6, 0x7e, 0xe5, 0xe0, 0x5f,
|
||||||
|
0x61, 0xc1, 0x20, 0xb4, 0xb9, 0xb4, 0x33, 0x08, 0x70, 0xe4, 0xdf, 0x89, 0x56, 0xed, 0x01,
|
||||||
|
0x29, 0x46, 0x77, 0x5f, 0x8c, 0xb8, 0xa9, 0xf5, 0x1e, 0x2e, 0xb3, 0xb9, 0xbf, 0xe0, 0x09,
|
||||||
|
0xb7, 0x8d, 0x28, 0xd4, 0xa6, 0xc3, 0xb8, 0x1e, 0x1f, 0x07, 0xeb, 0xb4, 0x12, 0x0b, 0x95,
|
||||||
|
0xb8, 0x85, 0x30, 0xfd, 0xdc, 0x39, 0x13, 0xd0, 0x7c, 0xdc, 0x8f, 0xed, 0xf9, 0xc9, 0xa3,
|
||||||
|
0xc1};
|
||||||
|
// p
|
||||||
|
static constexpr CryptoPP::byte Prime1[] = {
|
||||||
|
0xF9, 0x67, 0xAD, 0x99, 0x12, 0x31, 0x0C, 0x56, 0xA2, 0x2E, 0x16, 0x1C, 0x46, 0xB3, 0x4D,
|
||||||
|
0x5B, 0x43, 0xBE, 0x42, 0xA2, 0xF6, 0x86, 0x96, 0x80, 0x42, 0xC3, 0xC7, 0x3F, 0xC3, 0x42,
|
||||||
|
0xF5, 0x87, 0x49, 0x33, 0x9F, 0x07, 0x5D, 0x6E, 0x2C, 0x04, 0xFD, 0xE3, 0xE1, 0xB2, 0xAE,
|
||||||
|
0x0A, 0x0C, 0xF0, 0xC7, 0xA6, 0x1C, 0xA1, 0x63, 0x50, 0xC8, 0x09, 0x9C, 0x51, 0x24, 0x52,
|
||||||
|
0x6C, 0x5E, 0x5E, 0xBD, 0x1E, 0x27, 0x06, 0xBB, 0xBC, 0x9E, 0x94, 0xE1, 0x35, 0xD4, 0x6D,
|
||||||
|
0xB3, 0xCB, 0x3C, 0x68, 0xDD, 0x68, 0xB3, 0xFE, 0x6C, 0xCB, 0x8D, 0x82, 0x20, 0x76, 0x23,
|
||||||
|
0x63, 0xB7, 0xE9, 0x68, 0x10, 0x01, 0x4E, 0xDC, 0xBA, 0x27, 0x5D, 0x01, 0xC1, 0x2D, 0x80,
|
||||||
|
0x5E, 0x2B, 0xAF, 0x82, 0x6B, 0xD8, 0x84, 0xB6, 0x10, 0x52, 0x86, 0xA7, 0x89, 0x8E, 0xAE,
|
||||||
|
0x9A, 0xE2, 0x89, 0xC6, 0xF7, 0xD5, 0x87, 0xFB};
|
||||||
|
// q
|
||||||
|
static constexpr CryptoPP::byte Prime2[] = {
|
||||||
|
0xD7, 0xA1, 0x0F, 0x9A, 0x8B, 0xF2, 0xC9, 0x11, 0x95, 0x32, 0x9A, 0x8C, 0xF0, 0xD9, 0x40,
|
||||||
|
0x47, 0xF5, 0x68, 0xA0, 0x0D, 0xBD, 0xC1, 0xFC, 0x43, 0x2F, 0x65, 0xF9, 0xC3, 0x61, 0x0F,
|
||||||
|
0x25, 0x77, 0x54, 0xAD, 0xD7, 0x58, 0xAC, 0x84, 0x40, 0x60, 0x8D, 0x3F, 0xF3, 0x65, 0x89,
|
||||||
|
0x75, 0xB5, 0xC6, 0x2C, 0x51, 0x1A, 0x2F, 0x1F, 0x22, 0xE4, 0x43, 0x11, 0x54, 0xBE, 0xC9,
|
||||||
|
0xB4, 0xC7, 0xB5, 0x1B, 0x05, 0x0B, 0xBC, 0x56, 0x9A, 0xCD, 0x4A, 0xD9, 0x73, 0x68, 0x5E,
|
||||||
|
0x5C, 0xFB, 0x92, 0xB7, 0x8B, 0x0D, 0xFF, 0xF5, 0x07, 0xCA, 0xB4, 0xC8, 0x9B, 0x96, 0x3C,
|
||||||
|
0x07, 0x9E, 0x3E, 0x6B, 0x2A, 0x11, 0xF2, 0x8A, 0xB1, 0x8A, 0xD7, 0x2E, 0x1B, 0xA5, 0x53,
|
||||||
|
0x24, 0x06, 0xED, 0x50, 0xB8, 0x90, 0x67, 0xB1, 0xE2, 0x41, 0xC6, 0x92, 0x01, 0xEE, 0x10,
|
||||||
|
0xF0, 0x61, 0xBB, 0xFB, 0xB2, 0x7D, 0x4A, 0x73};
|
||||||
|
static constexpr CryptoPP::byte PrivateExponent[] = {
|
||||||
|
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};
|
||||||
|
};
|
|
@ -40,10 +40,6 @@ public:
|
||||||
return ORBIS_KERNEL_ERROR_EBADF;
|
return ORBIS_KERNEL_ERROR_EBADF;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual size_t pwritev(const Libraries::Kernel::SceKernelIovec* iov, int iovcnt, u64 offset) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EBADF;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual s64 lseek(s64 offset, int whence) {
|
virtual s64 lseek(s64 offset, int whence) {
|
||||||
return ORBIS_KERNEL_ERROR_EBADF;
|
return ORBIS_KERNEL_ERROR_EBADF;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "random_device.h"
|
#include "random_device.h"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "srandom_device.h"
|
#include "srandom_device.h"
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <ctime>
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "urandom_device.h"
|
#include "urandom_device.h"
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include "SDL3/SDL_log.h"
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/singleton.h"
|
#include "common/singleton.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
@ -118,6 +117,22 @@ void L::DrawMenuBar() {
|
||||||
|
|
||||||
EndMainMenuBar();
|
EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsKeyPressed(ImGuiKey_F9, false)) {
|
||||||
|
if (io.KeyCtrl && io.KeyAlt) {
|
||||||
|
if (!DebugState.ShouldPauseInSubmit()) {
|
||||||
|
DebugState.RequestFrameDump(dump_frame_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!io.KeyCtrl && !io.KeyAlt) {
|
||||||
|
if (isSystemPaused) {
|
||||||
|
DebugState.ResumeGuestThreads();
|
||||||
|
} else {
|
||||||
|
DebugState.PauseGuestThreads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (open_popup_options) {
|
if (open_popup_options) {
|
||||||
OpenPopup("GPU Tools Options");
|
OpenPopup("GPU Tools Options");
|
||||||
just_opened_options = true;
|
just_opened_options = true;
|
||||||
|
@ -366,32 +381,6 @@ void L::Draw() {
|
||||||
visibility_toggled = true;
|
visibility_toggled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(ImGuiKey_F9, false)) {
|
|
||||||
if (io.KeyCtrl && io.KeyAlt) {
|
|
||||||
if (!DebugState.ShouldPauseInSubmit()) {
|
|
||||||
DebugState.RequestFrameDump(dump_frame_count);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (DebugState.IsGuestThreadsPaused()) {
|
|
||||||
DebugState.ResumeGuestThreads();
|
|
||||||
SDL_Log("Game resumed from Keyboard");
|
|
||||||
show_pause_status = false;
|
|
||||||
} else {
|
|
||||||
DebugState.PauseGuestThreads();
|
|
||||||
SDL_Log("Game paused from Keyboard");
|
|
||||||
show_pause_status = true;
|
|
||||||
}
|
|
||||||
visibility_toggled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_pause_status) {
|
|
||||||
ImVec2 pos = ImVec2(10, 10);
|
|
||||||
ImU32 color = IM_COL32(255, 255, 255, 255);
|
|
||||||
|
|
||||||
ImGui::GetForegroundDrawList()->AddText(pos, color, "Game Paused Press F9 to Resume");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (show_simple_fps) {
|
if (show_simple_fps) {
|
||||||
if (Begin("Video Info", nullptr,
|
if (Begin("Video Info", nullptr,
|
||||||
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration |
|
ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoDecoration |
|
||||||
|
|
|
@ -19,7 +19,6 @@ public:
|
||||||
static void SetupSettings();
|
static void SetupSettings();
|
||||||
|
|
||||||
void Draw() override;
|
void Draw() override;
|
||||||
bool show_pause_status = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core::Devtools
|
} // namespace Core::Devtools
|
||||||
|
|
|
@ -1,14 +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 "options.h"
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
|
|
||||||
#include "video_core/renderer_vulkan/vk_presenter.h"
|
#include "options.h"
|
||||||
|
|
||||||
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
|
||||||
|
|
||||||
namespace Core::Devtools {
|
namespace Core::Devtools {
|
||||||
|
|
||||||
|
@ -17,7 +12,6 @@ TOptions Options;
|
||||||
void LoadOptionsConfig(const char* line) {
|
void LoadOptionsConfig(const char* line) {
|
||||||
char str[512];
|
char str[512];
|
||||||
int i;
|
int i;
|
||||||
float f;
|
|
||||||
if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) {
|
if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) {
|
||||||
Options.disassembler_cli_isa = str;
|
Options.disassembler_cli_isa = str;
|
||||||
return;
|
return;
|
||||||
|
@ -30,26 +24,12 @@ void LoadOptionsConfig(const char* line) {
|
||||||
Options.frame_dump_render_on_collapse = i != 0;
|
Options.frame_dump_render_on_collapse = i != 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sscanf(line, "fsr_enabled=%d", &i) == 1) {
|
|
||||||
presenter->GetFsrSettingsRef().enable = i != 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (sscanf(line, "fsr_rcas_enabled=%d", &i) == 1) {
|
|
||||||
presenter->GetFsrSettingsRef().use_rcas = i != 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (sscanf(line, "fsr_rcas_attenuation=%f", &f) == 1) {
|
|
||||||
presenter->GetFsrSettingsRef().rcas_attenuation = f;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
||||||
buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str());
|
buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str());
|
||||||
buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str());
|
buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str());
|
||||||
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
|
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
|
||||||
buf->appendf("fsr_enabled=%d\n", presenter->GetFsrSettingsRef().enable);
|
|
||||||
buf->appendf("fsr_rcas_enabled=%d\n", presenter->GetFsrSettingsRef().use_rcas);
|
|
||||||
buf->appendf("fsr_rcas_attenuation=%f\n", presenter->GetFsrSettingsRef().rcas_attenuation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Core::Devtools
|
} // namespace Core::Devtools
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <ctime>
|
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <magic_enum/magic_enum.hpp>
|
#include <magic_enum/magic_enum.hpp>
|
||||||
|
|
|
@ -627,56 +627,65 @@ void TextEditor::HandleKeyboardInputs() {
|
||||||
io.WantCaptureKeyboard = true;
|
io.WantCaptureKeyboard = true;
|
||||||
io.WantTextInput = true;
|
io.WantTextInput = true;
|
||||||
|
|
||||||
if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Z))
|
if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Z)))
|
||||||
Undo();
|
Undo();
|
||||||
else if (!IsReadOnly() && !ctrl && !shift && alt && ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
else if (!IsReadOnly() && !ctrl && !shift && alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||||
Undo();
|
Undo();
|
||||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Y))
|
else if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Y)))
|
||||||
Redo();
|
Redo();
|
||||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_UpArrow))
|
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
|
||||||
MoveUp(1, shift);
|
MoveUp(1, shift);
|
||||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_DownArrow))
|
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
|
||||||
MoveDown(1, shift);
|
MoveDown(1, shift);
|
||||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_LeftArrow))
|
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
|
||||||
MoveLeft(1, shift, ctrl);
|
MoveLeft(1, shift, ctrl);
|
||||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_RightArrow))
|
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
|
||||||
MoveRight(1, shift, ctrl);
|
MoveRight(1, shift, ctrl);
|
||||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_PageUp))
|
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)))
|
||||||
MoveUp(GetPageSize() - 4, shift);
|
MoveUp(GetPageSize() - 4, shift);
|
||||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_PageDown))
|
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)))
|
||||||
MoveDown(GetPageSize() - 4, shift);
|
MoveDown(GetPageSize() - 4, shift);
|
||||||
else if (!alt && ctrl && ImGui::IsKeyPressed(ImGuiKey_Home))
|
else if (!alt && ctrl && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
|
||||||
MoveTop(shift);
|
MoveTop(shift);
|
||||||
else if (ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_End))
|
else if (ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
|
||||||
MoveBottom(shift);
|
MoveBottom(shift);
|
||||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Home))
|
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
|
||||||
MoveHome(shift);
|
MoveHome(shift);
|
||||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_End))
|
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
|
||||||
MoveEnd(shift);
|
MoveEnd(shift);
|
||||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
|
||||||
Delete();
|
Delete();
|
||||||
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||||
ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||||
Backspace();
|
Backspace();
|
||||||
else if (!ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
else if (!ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||||
mOverwrite ^= true;
|
mOverwrite ^= true;
|
||||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||||
Copy();
|
Copy();
|
||||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_C))
|
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C)))
|
||||||
Copy();
|
Copy();
|
||||||
else if (!IsReadOnly() && !ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
else if (!IsReadOnly() && !ctrl && shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||||
Paste();
|
Paste();
|
||||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_V))
|
else if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V)))
|
||||||
Paste();
|
Paste();
|
||||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_X))
|
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_X)))
|
||||||
Cut();
|
Cut();
|
||||||
else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
|
||||||
Cut();
|
Cut();
|
||||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_A))
|
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_A)))
|
||||||
SelectAll();
|
SelectAll();
|
||||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Enter))
|
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
|
||||||
EnterCharacter('\n', false);
|
EnterCharacter('\n', false);
|
||||||
else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Tab))
|
else if (!IsReadOnly() && !ctrl && !alt &&
|
||||||
|
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab)))
|
||||||
EnterCharacter('\t', shift);
|
EnterCharacter('\t', shift);
|
||||||
|
|
||||||
if (!IsReadOnly() && !io.InputQueueCharacters.empty()) {
|
if (!IsReadOnly() && !io.InputQueueCharacters.empty()) {
|
||||||
|
|
473
src/core/file_format/pkg.cpp
Normal file
473
src/core/file_format/pkg.cpp
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
#include "common/io_file.h"
|
||||||
|
#include "common/logging/formatter.h"
|
||||||
|
#include "core/file_format/pkg.h"
|
||||||
|
#include "core/file_format/pkg_type.h"
|
||||||
|
|
||||||
|
static void DecompressPFSC(std::span<char> compressed_data, std::span<char> decompressed_data) {
|
||||||
|
z_stream decompressStream;
|
||||||
|
decompressStream.zalloc = Z_NULL;
|
||||||
|
decompressStream.zfree = Z_NULL;
|
||||||
|
decompressStream.opaque = Z_NULL;
|
||||||
|
|
||||||
|
if (inflateInit(&decompressStream) != Z_OK) {
|
||||||
|
// std::cerr << "Error initializing zlib for deflation." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
decompressStream.avail_in = compressed_data.size();
|
||||||
|
decompressStream.next_in = reinterpret_cast<unsigned char*>(compressed_data.data());
|
||||||
|
decompressStream.avail_out = decompressed_data.size();
|
||||||
|
decompressStream.next_out = reinterpret_cast<unsigned char*>(decompressed_data.data());
|
||||||
|
|
||||||
|
if (inflate(&decompressStream, Z_FINISH)) {
|
||||||
|
}
|
||||||
|
if (inflateEnd(&decompressStream) != Z_OK) {
|
||||||
|
// std::cerr << "Error ending zlib inflate" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetPFSCOffset(std::span<const u8> pfs_image) {
|
||||||
|
static constexpr u32 PfscMagic = 0x43534650;
|
||||||
|
u32 value;
|
||||||
|
for (u32 i = 0x20000; i < pfs_image.size(); i += 0x10000) {
|
||||||
|
std::memcpy(&value, &pfs_image[i], sizeof(u32));
|
||||||
|
if (value == PfscMagic)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PKG::PKG() = default;
|
||||||
|
|
||||||
|
PKG::~PKG() = default;
|
||||||
|
|
||||||
|
bool PKG::Open(const std::filesystem::path& filepath, std::string& failreason) {
|
||||||
|
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||||
|
if (!file.IsOpen()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pkgSize = file.GetSize();
|
||||||
|
|
||||||
|
file.Read(pkgheader);
|
||||||
|
if (pkgheader.magic != 0x7F434E54)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const auto& flag : flagNames) {
|
||||||
|
if (isFlagSet(pkgheader.pkg_content_flags, flag.first)) {
|
||||||
|
if (!pkgFlags.empty())
|
||||||
|
pkgFlags += (", ");
|
||||||
|
pkgFlags += (flag.second);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find title id it is part of pkg_content_id starting at offset 0x40
|
||||||
|
file.Seek(0x47); // skip first 7 characters of content_id
|
||||||
|
file.Read(pkgTitleID);
|
||||||
|
|
||||||
|
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||||
|
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||||
|
|
||||||
|
if (!file.Seek(offset)) {
|
||||||
|
failreason = "Failed to seek to PKG table entry offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n_files; i++) {
|
||||||
|
PKGEntry entry{};
|
||||||
|
file.Read(entry.id);
|
||||||
|
file.Read(entry.filename_offset);
|
||||||
|
file.Read(entry.flags1);
|
||||||
|
file.Read(entry.flags2);
|
||||||
|
file.Read(entry.offset);
|
||||||
|
file.Read(entry.size);
|
||||||
|
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||||
|
|
||||||
|
// Try to figure out the name
|
||||||
|
const auto name = GetEntryNameByType(entry.id);
|
||||||
|
if (name == "param.sfo") {
|
||||||
|
sfo.clear();
|
||||||
|
if (!file.Seek(entry.offset)) {
|
||||||
|
failreason = "Failed to seek to param.sfo offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sfo.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(sfo.data(), entry.size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.Close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::path& extract,
|
||||||
|
std::string& failreason) {
|
||||||
|
extract_path = extract;
|
||||||
|
pkgpath = filepath;
|
||||||
|
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||||
|
if (!file.IsOpen()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pkgSize = file.GetSize();
|
||||||
|
file.ReadRaw<u8>(&pkgheader, sizeof(PKGHeader));
|
||||||
|
|
||||||
|
if (pkgheader.magic != 0x7F434E54)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pkgheader.pkg_size > pkgSize) {
|
||||||
|
failreason = "PKG file size is different";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((pkgheader.pkg_content_size + pkgheader.pkg_content_offset) > pkgheader.pkg_size) {
|
||||||
|
failreason = "Content size is bigger than pkg size";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 offset = pkgheader.pkg_table_entry_offset;
|
||||||
|
u32 n_files = pkgheader.pkg_table_entry_count;
|
||||||
|
|
||||||
|
std::array<u8, 64> concatenated_ivkey_dk3;
|
||||||
|
std::array<u8, 32> seed_digest;
|
||||||
|
std::array<std::array<u8, 32>, 7> digest1;
|
||||||
|
std::array<std::array<u8, 256>, 7> key1;
|
||||||
|
std::array<u8, 256> imgkeydata;
|
||||||
|
|
||||||
|
if (!file.Seek(offset)) {
|
||||||
|
failreason = "Failed to seek to PKG table entry offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < n_files; i++) {
|
||||||
|
PKGEntry entry{};
|
||||||
|
file.Read(entry.id);
|
||||||
|
file.Read(entry.filename_offset);
|
||||||
|
file.Read(entry.flags1);
|
||||||
|
file.Read(entry.flags2);
|
||||||
|
file.Read(entry.offset);
|
||||||
|
file.Read(entry.size);
|
||||||
|
file.Seek(8, Common::FS::SeekOrigin::CurrentPosition);
|
||||||
|
|
||||||
|
auto currentPos = file.Tell();
|
||||||
|
|
||||||
|
// Try to figure out the name
|
||||||
|
const auto name = GetEntryNameByType(entry.id);
|
||||||
|
const auto filepath = extract_path / "sce_sys" / name;
|
||||||
|
std::filesystem::create_directories(filepath.parent_path());
|
||||||
|
|
||||||
|
if (name.empty()) {
|
||||||
|
// Just print with id
|
||||||
|
Common::FS::IOFile out(extract_path / "sce_sys" / std::to_string(entry.id),
|
||||||
|
Common::FS::FileAccessMode::Write);
|
||||||
|
if (!file.Seek(entry.offset)) {
|
||||||
|
failreason = "Failed to seek to PKG entry offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> data;
|
||||||
|
data.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(data.data(), entry.size);
|
||||||
|
out.WriteRaw<u8>(data.data(), entry.size);
|
||||||
|
out.Close();
|
||||||
|
|
||||||
|
file.Seek(currentPos);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry.id == 0x1) { // DIGESTS, seek;
|
||||||
|
// file.Seek(entry.offset, fsSeekSet);
|
||||||
|
} else if (entry.id == 0x10) { // ENTRY_KEYS, seek;
|
||||||
|
file.Seek(entry.offset);
|
||||||
|
file.Read(seed_digest);
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
file.Read(digest1[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
file.Read(key1[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
PKG::crypto.RSA2048Decrypt(dk3_, key1[3], true); // decrypt DK3
|
||||||
|
} else if (entry.id == 0x20) { // IMAGE_KEY, seek; IV_KEY
|
||||||
|
file.Seek(entry.offset);
|
||||||
|
file.Read(imgkeydata);
|
||||||
|
|
||||||
|
// The Concatenated iv + dk3 imagekey for HASH256
|
||||||
|
std::memcpy(concatenated_ivkey_dk3.data(), &entry, sizeof(entry));
|
||||||
|
std::memcpy(concatenated_ivkey_dk3.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
||||||
|
|
||||||
|
PKG::crypto.ivKeyHASH256(concatenated_ivkey_dk3, ivKey); // ivkey_
|
||||||
|
// imgkey_ to use for last step to get ekpfs
|
||||||
|
PKG::crypto.aesCbcCfb128Decrypt(ivKey, imgkeydata, imgKey);
|
||||||
|
// ekpfs key to get data and tweak keys.
|
||||||
|
PKG::crypto.RSA2048Decrypt(ekpfsKey, imgKey, false);
|
||||||
|
} else if (entry.id == 0x80) {
|
||||||
|
// GENERAL_DIGESTS, seek;
|
||||||
|
// file.Seek(entry.offset, fsSeekSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
Common::FS::IOFile out(extract_path / "sce_sys" / name, Common::FS::FileAccessMode::Write);
|
||||||
|
if (!file.Seek(entry.offset)) {
|
||||||
|
failreason = "Failed to seek to PKG entry offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<u8> data;
|
||||||
|
data.resize(entry.size);
|
||||||
|
file.ReadRaw<u8>(data.data(), entry.size);
|
||||||
|
out.WriteRaw<u8>(data.data(), entry.size);
|
||||||
|
out.Close();
|
||||||
|
|
||||||
|
// Decrypt Np stuff and overwrite.
|
||||||
|
if (entry.id == 0x400 || entry.id == 0x401 || entry.id == 0x402 ||
|
||||||
|
entry.id == 0x403) { // somehow 0x401 is not decrypting
|
||||||
|
decNp.resize(entry.size);
|
||||||
|
if (!file.Seek(entry.offset)) {
|
||||||
|
failreason = "Failed to seek to PKG entry offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::memcpy(concatenated_ivkey_dk3_.data(), &entry, sizeof(entry));
|
||||||
|
std::memcpy(concatenated_ivkey_dk3_.data() + sizeof(entry), dk3_.data(), sizeof(dk3_));
|
||||||
|
PKG::crypto.ivKeyHASH256(concatenated_ivkey_dk3_, ivKey);
|
||||||
|
PKG::crypto.aesCbcCfb128DecryptEntry(ivKey, cipherNp, decNp);
|
||||||
|
|
||||||
|
Common::FS::IOFile out(extract_path / "sce_sys" / name,
|
||||||
|
Common::FS::FileAccessMode::Write);
|
||||||
|
out.Write(decNp);
|
||||||
|
out.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
file.Seek(currentPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the seed
|
||||||
|
std::array<u8, 16> seed;
|
||||||
|
if (!file.Seek(pkgheader.pfs_image_offset + 0x370)) {
|
||||||
|
failreason = "Failed to seek to PFS image offset";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
file.Read(seed);
|
||||||
|
|
||||||
|
// Get data and tweak keys.
|
||||||
|
PKG::crypto.PfsGenCryptoKey(ekpfsKey, seed, dataKey, tweakKey);
|
||||||
|
const u32 length = pkgheader.pfs_cache_size * 0x2; // Seems to be ok.
|
||||||
|
|
||||||
|
int num_blocks = 0;
|
||||||
|
std::vector<u8> pfsc(length);
|
||||||
|
if (length != 0) {
|
||||||
|
// Read encrypted pfs_image
|
||||||
|
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::memcpy(pfsc.data(), pfs_decrypted.data() + pfsc_offset, length - pfsc_offset);
|
||||||
|
|
||||||
|
PFSCHdr pfsChdr;
|
||||||
|
std::memcpy(&pfsChdr, pfsc.data(), sizeof(pfsChdr));
|
||||||
|
|
||||||
|
num_blocks = (int)(pfsChdr.data_length / pfsChdr.block_sz2);
|
||||||
|
sectorMap.resize(num_blocks + 1); // 8 bytes, need extra 1 to get the last offset.
|
||||||
|
|
||||||
|
for (int i = 0; i < num_blocks + 1; i++) {
|
||||||
|
std::memcpy(§orMap[i], pfsc.data() + pfsChdr.block_offsets + i * 8, 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ent_size = 0;
|
||||||
|
u32 ndinode = 0;
|
||||||
|
int ndinode_counter = 0;
|
||||||
|
bool dinode_reached = false;
|
||||||
|
bool uroot_reached = false;
|
||||||
|
std::vector<char> compressedData;
|
||||||
|
std::vector<char> decompressedData(0x10000);
|
||||||
|
|
||||||
|
// Get iNdoes and Dirents.
|
||||||
|
for (int i = 0; i < num_blocks; i++) {
|
||||||
|
const u64 sectorOffset = sectorMap[i];
|
||||||
|
const u64 sectorSize = sectorMap[i + 1] - sectorOffset;
|
||||||
|
|
||||||
|
compressedData.resize(sectorSize);
|
||||||
|
std::memcpy(compressedData.data(), pfsc.data() + sectorOffset, sectorSize);
|
||||||
|
|
||||||
|
if (sectorSize == 0x10000) // Uncompressed data
|
||||||
|
std::memcpy(decompressedData.data(), compressedData.data(), 0x10000);
|
||||||
|
else if (sectorSize < 0x10000) // Compressed data
|
||||||
|
DecompressPFSC(compressedData, decompressedData);
|
||||||
|
|
||||||
|
if (i == 0) {
|
||||||
|
std::memcpy(&ndinode, decompressedData.data() + 0x30, 4); // number of folders and files
|
||||||
|
}
|
||||||
|
|
||||||
|
int occupied_blocks =
|
||||||
|
(ndinode * 0xA8) / 0x10000; // how many blocks(0x10000) are taken by iNodes.
|
||||||
|
if (((ndinode * 0xA8) % 0x10000) != 0)
|
||||||
|
occupied_blocks += 1;
|
||||||
|
|
||||||
|
if (i >= 1 && i <= occupied_blocks) { // Get all iNodes, gives type, file size and location.
|
||||||
|
for (int p = 0; p < 0x10000; p += 0xA8) {
|
||||||
|
Inode node;
|
||||||
|
std::memcpy(&node, &decompressedData[p], sizeof(node));
|
||||||
|
if (node.Mode == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iNodeBuf.push_back(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// let's deal with the root/uroot entries here.
|
||||||
|
// Sometimes it's more than 2 entries (Tomb Raider Remastered)
|
||||||
|
const std::string_view flat_path_table(&decompressedData[0x10], 15);
|
||||||
|
if (flat_path_table == "flat_path_table") {
|
||||||
|
uroot_reached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uroot_reached) {
|
||||||
|
for (int i = 0; i < 0x10000; i += ent_size) {
|
||||||
|
Dirent dirent;
|
||||||
|
std::memcpy(&dirent, &decompressedData[i], sizeof(dirent));
|
||||||
|
ent_size = dirent.entsize;
|
||||||
|
if (dirent.ino != 0) {
|
||||||
|
ndinode_counter++;
|
||||||
|
} else {
|
||||||
|
// Set the the folder according to the current inode.
|
||||||
|
// Can be 2 or more (rarely)
|
||||||
|
auto parent_path = extract_path.parent_path();
|
||||||
|
auto title_id = GetTitleID();
|
||||||
|
|
||||||
|
if (parent_path.filename() != title_id &&
|
||||||
|
!fmt::UTF(extract_path.u8string()).data.ends_with("-UPDATE")) {
|
||||||
|
extractPaths[ndinode_counter] = parent_path / title_id;
|
||||||
|
} else {
|
||||||
|
// DLCs path has different structure
|
||||||
|
extractPaths[ndinode_counter] = extract_path;
|
||||||
|
}
|
||||||
|
uroot_reached = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char dot = decompressedData[0x10];
|
||||||
|
const std::string_view dotdot(&decompressedData[0x28], 2);
|
||||||
|
if (dot == '.' && dotdot == "..") {
|
||||||
|
dinode_reached = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get folder and file names.
|
||||||
|
bool end_reached = false;
|
||||||
|
if (dinode_reached) {
|
||||||
|
for (int j = 0; j < 0x10000; j += ent_size) { // Skip the first parent and child.
|
||||||
|
Dirent dirent;
|
||||||
|
std::memcpy(&dirent, &decompressedData[j], sizeof(dirent));
|
||||||
|
|
||||||
|
// Stop here and continue the main loop
|
||||||
|
if (dirent.ino == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ent_size = dirent.entsize;
|
||||||
|
auto& table = fsTable.emplace_back();
|
||||||
|
table.name = std::string(dirent.name, dirent.namelen);
|
||||||
|
table.inode = dirent.ino;
|
||||||
|
table.type = dirent.type;
|
||||||
|
|
||||||
|
if (table.type == PFS_CURRENT_DIR) {
|
||||||
|
current_dir = extractPaths[table.inode];
|
||||||
|
}
|
||||||
|
extractPaths[table.inode] = current_dir / std::filesystem::path(table.name);
|
||||||
|
|
||||||
|
if (table.type == PFS_FILE || table.type == PFS_DIR) {
|
||||||
|
if (table.type == PFS_DIR) { // Create dirs.
|
||||||
|
std::filesystem::create_directory(extractPaths[table.inode]);
|
||||||
|
}
|
||||||
|
ndinode_counter++;
|
||||||
|
if ((ndinode_counter + 1) == ndinode) // 1 for the image itself (root).
|
||||||
|
end_reached = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (end_reached) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PKG::ExtractFiles(const int index) {
|
||||||
|
int inode_number = fsTable[index].inode;
|
||||||
|
int inode_type = fsTable[index].type;
|
||||||
|
std::string inode_name = fsTable[index].name;
|
||||||
|
|
||||||
|
if (inode_type == PFS_FILE) {
|
||||||
|
int sector_loc = iNodeBuf[inode_number].loc;
|
||||||
|
int nblocks = iNodeBuf[inode_number].Blocks;
|
||||||
|
int bsize = iNodeBuf[inode_number].Size;
|
||||||
|
|
||||||
|
Common::FS::IOFile inflated;
|
||||||
|
inflated.Open(extractPaths[inode_number], Common::FS::FileAccessMode::Write);
|
||||||
|
|
||||||
|
Common::FS::IOFile pkgFile; // Open the file for each iteration to avoid conflict.
|
||||||
|
pkgFile.Open(pkgpath, Common::FS::FileAccessMode::Read);
|
||||||
|
|
||||||
|
int size_decompressed = 0;
|
||||||
|
std::vector<char> compressedData;
|
||||||
|
std::vector<char> decompressedData(0x10000);
|
||||||
|
|
||||||
|
u64 pfsc_buf_size = 0x11000; // extra 0x1000
|
||||||
|
std::vector<u8> pfsc(pfsc_buf_size);
|
||||||
|
std::vector<u8> pfs_decrypted(pfsc_buf_size);
|
||||||
|
|
||||||
|
for (int j = 0; j < nblocks; j++) {
|
||||||
|
u64 sectorOffset =
|
||||||
|
sectorMap[sector_loc + j]; // offset into PFSC_image and not pfs_image.
|
||||||
|
u64 sectorSize = sectorMap[sector_loc + j + 1] -
|
||||||
|
sectorOffset; // indicates if data is compressed or not.
|
||||||
|
u64 fileOffset = (pkgheader.pfs_image_offset + pfsc_offset + sectorOffset);
|
||||||
|
u64 currentSector1 =
|
||||||
|
(pfsc_offset + sectorOffset) / 0x1000; // block size is 0x1000 for xts decryption.
|
||||||
|
|
||||||
|
int sectorOffsetMask = (sectorOffset + pfsc_offset) & 0xFFFFF000;
|
||||||
|
int previousData = (sectorOffset + pfsc_offset) - sectorOffsetMask;
|
||||||
|
|
||||||
|
pkgFile.Seek(fileOffset - previousData);
|
||||||
|
pkgFile.Read(pfsc);
|
||||||
|
|
||||||
|
PKG::crypto.decryptPFS(dataKey, tweakKey, pfsc, pfs_decrypted, currentSector1);
|
||||||
|
|
||||||
|
compressedData.resize(sectorSize);
|
||||||
|
std::memcpy(compressedData.data(), pfs_decrypted.data() + previousData, sectorSize);
|
||||||
|
|
||||||
|
if (sectorSize == 0x10000) // Uncompressed data
|
||||||
|
std::memcpy(decompressedData.data(), compressedData.data(), 0x10000);
|
||||||
|
else if (sectorSize < 0x10000) // Compressed data
|
||||||
|
DecompressPFSC(compressedData, decompressedData);
|
||||||
|
|
||||||
|
size_decompressed += 0x10000;
|
||||||
|
|
||||||
|
if (j < nblocks - 1) {
|
||||||
|
inflated.WriteRaw<u8>(decompressedData.data(), decompressedData.size());
|
||||||
|
} else {
|
||||||
|
// This is to remove the zeros at the end of the file.
|
||||||
|
const u32 write_size = decompressedData.size() - (size_decompressed - bsize);
|
||||||
|
inflated.WriteRaw<u8>(decompressedData.data(), write_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pkgFile.Close();
|
||||||
|
inflated.Close();
|
||||||
|
}
|
||||||
|
}
|
174
src/core/file_format/pkg.h
Normal file
174
src/core/file_format/pkg.h
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/endian.h"
|
||||||
|
#include "core/crypto/crypto.h"
|
||||||
|
#include "pfs.h"
|
||||||
|
#include "trp.h"
|
||||||
|
|
||||||
|
struct PKGHeader {
|
||||||
|
u32_be magic; // Magic
|
||||||
|
u32_be pkg_type;
|
||||||
|
u32_be pkg_0x8; // unknown field
|
||||||
|
u32_be pkg_file_count;
|
||||||
|
u32_be pkg_table_entry_count;
|
||||||
|
u16_be pkg_sc_entry_count;
|
||||||
|
u16_be pkg_table_entry_count_2; // same as pkg_entry_count
|
||||||
|
u32_be pkg_table_entry_offset; // file table offset
|
||||||
|
u32_be pkg_sc_entry_data_size;
|
||||||
|
u64_be pkg_body_offset; // offset of PKG entries
|
||||||
|
u64_be pkg_body_size; // length of all PKG entries
|
||||||
|
u64_be pkg_content_offset;
|
||||||
|
u64_be pkg_content_size;
|
||||||
|
u8 pkg_content_id[0x24]; // packages' content ID as a 36-byte string
|
||||||
|
u8 pkg_padding[0xC]; // padding
|
||||||
|
u32_be pkg_drm_type; // DRM type
|
||||||
|
u32_be pkg_content_type; // Content type
|
||||||
|
u32_be pkg_content_flags; // Content flags
|
||||||
|
u32_be pkg_promote_size;
|
||||||
|
u32_be pkg_version_date;
|
||||||
|
u32_be pkg_version_hash;
|
||||||
|
u32_be pkg_0x088;
|
||||||
|
u32_be pkg_0x08C;
|
||||||
|
u32_be pkg_0x090;
|
||||||
|
u32_be pkg_0x094;
|
||||||
|
u32_be pkg_iro_tag;
|
||||||
|
u32_be pkg_drm_type_version;
|
||||||
|
|
||||||
|
u8 pkg_zeroes_1[0x60];
|
||||||
|
|
||||||
|
/* Digest table */
|
||||||
|
u8 digest_entries1[0x20]; // sha256 digest for main entry 1
|
||||||
|
u8 digest_entries2[0x20]; // sha256 digest for main entry 2
|
||||||
|
u8 digest_table_digest[0x20]; // sha256 digest for digest table
|
||||||
|
u8 digest_body_digest[0x20]; // sha256 digest for main table
|
||||||
|
|
||||||
|
u8 pkg_zeroes_2[0x280];
|
||||||
|
|
||||||
|
u32_be pkg_0x400;
|
||||||
|
|
||||||
|
u32_be pfs_image_count; // count of PFS images
|
||||||
|
u64_be pfs_image_flags; // PFS flags
|
||||||
|
u64_be pfs_image_offset; // offset to start of external PFS image
|
||||||
|
u64_be pfs_image_size; // size of external PFS image
|
||||||
|
u64_be mount_image_offset;
|
||||||
|
u64_be mount_image_size;
|
||||||
|
u64_be pkg_size;
|
||||||
|
u32_be pfs_signed_size;
|
||||||
|
u32_be pfs_cache_size;
|
||||||
|
u8 pfs_image_digest[0x20];
|
||||||
|
u8 pfs_signed_digest[0x20];
|
||||||
|
u64_be pfs_split_size_nth_0;
|
||||||
|
u64_be pfs_split_size_nth_1;
|
||||||
|
|
||||||
|
u8 pkg_zeroes_3[0xB50];
|
||||||
|
|
||||||
|
u8 pkg_digest[0x20];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class PKGContentFlag {
|
||||||
|
FIRST_PATCH = 0x100000,
|
||||||
|
PATCHGO = 0x200000,
|
||||||
|
REMASTER = 0x400000,
|
||||||
|
PS_CLOUD = 0x800000,
|
||||||
|
GD_AC = 0x2000000,
|
||||||
|
NON_GAME = 0x4000000,
|
||||||
|
UNKNOWN_0x8000000 = 0x8000000,
|
||||||
|
SUBSEQUENT_PATCH = 0x40000000,
|
||||||
|
DELTA_PATCH = 0x41000000,
|
||||||
|
CUMULATIVE_PATCH = 0x60000000
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PKGEntry {
|
||||||
|
u32_be id; // File ID, useful for files without a filename entry
|
||||||
|
u32_be filename_offset; // Offset into the filenames table (ID 0x200) where this file's name is
|
||||||
|
// located
|
||||||
|
u32_be flags1; // Flags including encrypted flag, etc
|
||||||
|
u32_be flags2; // Flags including encryption key index, etc
|
||||||
|
u32_be offset; // Offset into PKG to find the file
|
||||||
|
u32_be size; // Size of the file
|
||||||
|
u64_be padding; // blank padding
|
||||||
|
};
|
||||||
|
static_assert(sizeof(PKGEntry) == 32);
|
||||||
|
|
||||||
|
class PKG {
|
||||||
|
public:
|
||||||
|
PKG();
|
||||||
|
~PKG();
|
||||||
|
|
||||||
|
bool Open(const std::filesystem::path& filepath, std::string& failreason);
|
||||||
|
void ExtractFiles(const int index);
|
||||||
|
bool Extract(const std::filesystem::path& filepath, const std::filesystem::path& extract,
|
||||||
|
std::string& failreason);
|
||||||
|
|
||||||
|
std::vector<u8> sfo;
|
||||||
|
|
||||||
|
u32 GetNumberOfFiles() {
|
||||||
|
return fsTable.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 GetPkgSize() {
|
||||||
|
return pkgSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetPkgFlags() {
|
||||||
|
return pkgFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view GetTitleID() {
|
||||||
|
return std::string_view(pkgTitleID, 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
PKGHeader GetPkgHeader() {
|
||||||
|
return pkgheader;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isFlagSet(u32_be variable, PKGContentFlag flag) {
|
||||||
|
return (variable) & static_cast<u32>(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr std::array<std::pair<PKGContentFlag, std::string_view>, 10> flagNames = {
|
||||||
|
{{PKGContentFlag::FIRST_PATCH, "FIRST_PATCH"},
|
||||||
|
{PKGContentFlag::PATCHGO, "PATCHGO"},
|
||||||
|
{PKGContentFlag::REMASTER, "REMASTER"},
|
||||||
|
{PKGContentFlag::PS_CLOUD, "PS_CLOUD"},
|
||||||
|
{PKGContentFlag::GD_AC, "GD_AC"},
|
||||||
|
{PKGContentFlag::NON_GAME, "NON_GAME"},
|
||||||
|
{PKGContentFlag::UNKNOWN_0x8000000, "UNKNOWN_0x8000000"},
|
||||||
|
{PKGContentFlag::SUBSEQUENT_PATCH, "SUBSEQUENT_PATCH"},
|
||||||
|
{PKGContentFlag::DELTA_PATCH, "DELTA_PATCH"},
|
||||||
|
{PKGContentFlag::CUMULATIVE_PATCH, "CUMULATIVE_PATCH"}}};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Crypto crypto;
|
||||||
|
TRP trp;
|
||||||
|
u64 pkgSize = 0;
|
||||||
|
char pkgTitleID[9];
|
||||||
|
PKGHeader pkgheader;
|
||||||
|
std::string pkgFlags;
|
||||||
|
|
||||||
|
std::unordered_map<int, std::filesystem::path> extractPaths;
|
||||||
|
std::vector<pfs_fs_table> fsTable;
|
||||||
|
std::vector<Inode> iNodeBuf;
|
||||||
|
std::vector<u64> sectorMap;
|
||||||
|
u64 pfsc_offset;
|
||||||
|
|
||||||
|
std::array<u8, 32> dk3_;
|
||||||
|
std::array<u8, 32> ivKey;
|
||||||
|
std::array<u8, 256> imgKey;
|
||||||
|
std::array<u8, 32> ekpfsKey;
|
||||||
|
std::array<u8, 16> dataKey;
|
||||||
|
std::array<u8, 16> tweakKey;
|
||||||
|
std::vector<u8> decNp;
|
||||||
|
|
||||||
|
std::filesystem::path pkgpath;
|
||||||
|
std::filesystem::path current_dir;
|
||||||
|
std::filesystem::path extract_path;
|
||||||
|
};
|
638
src/core/file_format/pkg_type.cpp
Normal file
638
src/core/file_format/pkg_type.cpp
Normal file
|
@ -0,0 +1,638 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include "pkg_type.h"
|
||||||
|
|
||||||
|
struct PkgEntryValue {
|
||||||
|
u32 type;
|
||||||
|
std::string_view name;
|
||||||
|
|
||||||
|
operator u32() const noexcept {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr static std::array<PkgEntryValue, 611> PkgEntries = {{
|
||||||
|
{0x0001, "digests"},
|
||||||
|
{0x0010, "entry_keys"},
|
||||||
|
{0x0020, "image_key"},
|
||||||
|
{0x0080, "general_digests"},
|
||||||
|
{0x0100, "metas"},
|
||||||
|
{0x0200, "entry_names"},
|
||||||
|
{0x0400, "license.dat"},
|
||||||
|
{0x0401, "license.info"},
|
||||||
|
{0x0402, "nptitle.dat"},
|
||||||
|
{0x0403, "npbind.dat"},
|
||||||
|
{0x0404, "selfinfo.dat"},
|
||||||
|
{0x0406, "imageinfo.dat"},
|
||||||
|
{0x0407, "target-deltainfo.dat"},
|
||||||
|
{0x0408, "origin-deltainfo.dat"},
|
||||||
|
{0x0409, "psreserved.dat"},
|
||||||
|
{0x1000, "param.sfo"},
|
||||||
|
{0x1001, "playgo-chunk.dat"},
|
||||||
|
{0x1002, "playgo-chunk.sha"},
|
||||||
|
{0x1003, "playgo-manifest.xml"},
|
||||||
|
{0x1004, "pronunciation.xml"},
|
||||||
|
{0x1005, "pronunciation.sig"},
|
||||||
|
{0x1006, "pic1.png"},
|
||||||
|
{0x1007, "pubtoolinfo.dat"},
|
||||||
|
{0x1008, "app/playgo-chunk.dat"},
|
||||||
|
{0x1009, "app/playgo-chunk.sha"},
|
||||||
|
{0x100A, "app/playgo-manifest.xml"},
|
||||||
|
{0x100B, "shareparam.json"},
|
||||||
|
{0x100C, "shareoverlayimage.png"},
|
||||||
|
{0x100D, "save_data.png"},
|
||||||
|
{0x100E, "shareprivacyguardimage.png"},
|
||||||
|
{0x1200, "icon0.png"},
|
||||||
|
{0x1201, "icon0_00.png"},
|
||||||
|
{0x1202, "icon0_01.png"},
|
||||||
|
{0x1203, "icon0_02.png"},
|
||||||
|
{0x1204, "icon0_03.png"},
|
||||||
|
{0x1205, "icon0_04.png"},
|
||||||
|
{0x1206, "icon0_05.png"},
|
||||||
|
{0x1207, "icon0_06.png"},
|
||||||
|
{0x1208, "icon0_07.png"},
|
||||||
|
{0x1209, "icon0_08.png"},
|
||||||
|
{0x120A, "icon0_09.png"},
|
||||||
|
{0x120B, "icon0_10.png"},
|
||||||
|
{0x120C, "icon0_11.png"},
|
||||||
|
{0x120D, "icon0_12.png"},
|
||||||
|
{0x120E, "icon0_13.png"},
|
||||||
|
{0x120F, "icon0_14.png"},
|
||||||
|
{0x1210, "icon0_15.png"},
|
||||||
|
{0x1211, "icon0_16.png"},
|
||||||
|
{0x1212, "icon0_17.png"},
|
||||||
|
{0x1213, "icon0_18.png"},
|
||||||
|
{0x1214, "icon0_19.png"},
|
||||||
|
{0x1215, "icon0_20.png"},
|
||||||
|
{0x1216, "icon0_21.png"},
|
||||||
|
{0x1217, "icon0_22.png"},
|
||||||
|
{0x1218, "icon0_23.png"},
|
||||||
|
{0x1219, "icon0_24.png"},
|
||||||
|
{0x121A, "icon0_25.png"},
|
||||||
|
{0x121B, "icon0_26.png"},
|
||||||
|
{0x121C, "icon0_27.png"},
|
||||||
|
{0x121D, "icon0_28.png"},
|
||||||
|
{0x121E, "icon0_29.png"},
|
||||||
|
{0x121F, "icon0_30.png"},
|
||||||
|
{0x1220, "pic0.png"},
|
||||||
|
{0x1240, "snd0.at9"},
|
||||||
|
{0x1241, "pic1_00.png"},
|
||||||
|
{0x1242, "pic1_01.png"},
|
||||||
|
{0x1243, "pic1_02.png"},
|
||||||
|
{0x1244, "pic1_03.png"},
|
||||||
|
{0x1245, "pic1_04.png"},
|
||||||
|
{0x1246, "pic1_05.png"},
|
||||||
|
{0x1247, "pic1_06.png"},
|
||||||
|
{0x1248, "pic1_07.png"},
|
||||||
|
{0x1249, "pic1_08.png"},
|
||||||
|
{0x124A, "pic1_09.png"},
|
||||||
|
{0x124B, "pic1_10.png"},
|
||||||
|
{0x124C, "pic1_11.png"},
|
||||||
|
{0x124D, "pic1_12.png"},
|
||||||
|
{0x124E, "pic1_13.png"},
|
||||||
|
{0x124F, "pic1_14.png"},
|
||||||
|
{0x1250, "pic1_15.png"},
|
||||||
|
{0x1251, "pic1_16.png"},
|
||||||
|
{0x1252, "pic1_17.png"},
|
||||||
|
{0x1253, "pic1_18.png"},
|
||||||
|
{0x1254, "pic1_19.png"},
|
||||||
|
{0x1255, "pic1_20.png"},
|
||||||
|
{0x1256, "pic1_21.png"},
|
||||||
|
{0x1257, "pic1_22.png"},
|
||||||
|
{0x1258, "pic1_23.png"},
|
||||||
|
{0x1259, "pic1_24.png"},
|
||||||
|
{0x125A, "pic1_25.png"},
|
||||||
|
{0x125B, "pic1_26.png"},
|
||||||
|
{0x125C, "pic1_27.png"},
|
||||||
|
{0x125D, "pic1_28.png"},
|
||||||
|
{0x125E, "pic1_29.png"},
|
||||||
|
{0x125F, "pic1_30.png"},
|
||||||
|
{0x1260, "changeinfo/changeinfo.xml"},
|
||||||
|
{0x1261, "changeinfo/changeinfo_00.xml"},
|
||||||
|
{0x1262, "changeinfo/changeinfo_01.xml"},
|
||||||
|
{0x1263, "changeinfo/changeinfo_02.xml"},
|
||||||
|
{0x1264, "changeinfo/changeinfo_03.xml"},
|
||||||
|
{0x1265, "changeinfo/changeinfo_04.xml"},
|
||||||
|
{0x1266, "changeinfo/changeinfo_05.xml"},
|
||||||
|
{0x1267, "changeinfo/changeinfo_06.xml"},
|
||||||
|
{0x1268, "changeinfo/changeinfo_07.xml"},
|
||||||
|
{0x1269, "changeinfo/changeinfo_08.xml"},
|
||||||
|
{0x126A, "changeinfo/changeinfo_09.xml"},
|
||||||
|
{0x126B, "changeinfo/changeinfo_10.xml"},
|
||||||
|
{0x126C, "changeinfo/changeinfo_11.xml"},
|
||||||
|
{0x126D, "changeinfo/changeinfo_12.xml"},
|
||||||
|
{0x126E, "changeinfo/changeinfo_13.xml"},
|
||||||
|
{0x126F, "changeinfo/changeinfo_14.xml"},
|
||||||
|
{0x1270, "changeinfo/changeinfo_15.xml"},
|
||||||
|
{0x1271, "changeinfo/changeinfo_16.xml"},
|
||||||
|
{0x1272, "changeinfo/changeinfo_17.xml"},
|
||||||
|
{0x1273, "changeinfo/changeinfo_18.xml"},
|
||||||
|
{0x1274, "changeinfo/changeinfo_19.xml"},
|
||||||
|
{0x1275, "changeinfo/changeinfo_20.xml"},
|
||||||
|
{0x1276, "changeinfo/changeinfo_21.xml"},
|
||||||
|
{0x1277, "changeinfo/changeinfo_22.xml"},
|
||||||
|
{0x1278, "changeinfo/changeinfo_23.xml"},
|
||||||
|
{0x1279, "changeinfo/changeinfo_24.xml"},
|
||||||
|
{0x127A, "changeinfo/changeinfo_25.xml"},
|
||||||
|
{0x127B, "changeinfo/changeinfo_26.xml"},
|
||||||
|
{0x127C, "changeinfo/changeinfo_27.xml"},
|
||||||
|
{0x127D, "changeinfo/changeinfo_28.xml"},
|
||||||
|
{0x127E, "changeinfo/changeinfo_29.xml"},
|
||||||
|
{0x127F, "changeinfo/changeinfo_30.xml"},
|
||||||
|
{0x1280, "icon0.dds"},
|
||||||
|
{0x1281, "icon0_00.dds"},
|
||||||
|
{0x1282, "icon0_01.dds"},
|
||||||
|
{0x1283, "icon0_02.dds"},
|
||||||
|
{0x1284, "icon0_03.dds"},
|
||||||
|
{0x1285, "icon0_04.dds"},
|
||||||
|
{0x1286, "icon0_05.dds"},
|
||||||
|
{0x1287, "icon0_06.dds"},
|
||||||
|
{0x1288, "icon0_07.dds"},
|
||||||
|
{0x1289, "icon0_08.dds"},
|
||||||
|
{0x128A, "icon0_09.dds"},
|
||||||
|
{0x128B, "icon0_10.dds"},
|
||||||
|
{0x128C, "icon0_11.dds"},
|
||||||
|
{0x128D, "icon0_12.dds"},
|
||||||
|
{0x128E, "icon0_13.dds"},
|
||||||
|
{0x128F, "icon0_14.dds"},
|
||||||
|
{0x1290, "icon0_15.dds"},
|
||||||
|
{0x1291, "icon0_16.dds"},
|
||||||
|
{0x1292, "icon0_17.dds"},
|
||||||
|
{0x1293, "icon0_18.dds"},
|
||||||
|
{0x1294, "icon0_19.dds"},
|
||||||
|
{0x1295, "icon0_20.dds"},
|
||||||
|
{0x1296, "icon0_21.dds"},
|
||||||
|
{0x1297, "icon0_22.dds"},
|
||||||
|
{0x1298, "icon0_23.dds"},
|
||||||
|
{0x1299, "icon0_24.dds"},
|
||||||
|
{0x129A, "icon0_25.dds"},
|
||||||
|
{0x129B, "icon0_26.dds"},
|
||||||
|
{0x129C, "icon0_27.dds"},
|
||||||
|
{0x129D, "icon0_28.dds"},
|
||||||
|
{0x129E, "icon0_29.dds"},
|
||||||
|
{0x129F, "icon0_30.dds"},
|
||||||
|
{0x12A0, "pic0.dds"},
|
||||||
|
{0x12C0, "pic1.dds"},
|
||||||
|
{0x12C1, "pic1_00.dds"},
|
||||||
|
{0x12C2, "pic1_01.dds"},
|
||||||
|
{0x12C3, "pic1_02.dds"},
|
||||||
|
{0x12C4, "pic1_03.dds"},
|
||||||
|
{0x12C5, "pic1_04.dds"},
|
||||||
|
{0x12C6, "pic1_05.dds"},
|
||||||
|
{0x12C7, "pic1_06.dds"},
|
||||||
|
{0x12C8, "pic1_07.dds"},
|
||||||
|
{0x12C9, "pic1_08.dds"},
|
||||||
|
{0x12CA, "pic1_09.dds"},
|
||||||
|
{0x12CB, "pic1_10.dds"},
|
||||||
|
{0x12CC, "pic1_11.dds"},
|
||||||
|
{0x12CD, "pic1_12.dds"},
|
||||||
|
{0x12CE, "pic1_13.dds"},
|
||||||
|
{0x12CF, "pic1_14.dds"},
|
||||||
|
{0x12D0, "pic1_15.dds"},
|
||||||
|
{0x12D1, "pic1_16.dds"},
|
||||||
|
{0x12D2, "pic1_17.dds"},
|
||||||
|
{0x12D3, "pic1_18.dds"},
|
||||||
|
{0x12D4, "pic1_19.dds"},
|
||||||
|
{0x12D5, "pic1_20.dds"},
|
||||||
|
{0x12D6, "pic1_21.dds"},
|
||||||
|
{0x12D7, "pic1_22.dds"},
|
||||||
|
{0x12D8, "pic1_23.dds"},
|
||||||
|
{0x12D9, "pic1_24.dds"},
|
||||||
|
{0x12DA, "pic1_25.dds"},
|
||||||
|
{0x12DB, "pic1_26.dds"},
|
||||||
|
{0x12DC, "pic1_27.dds"},
|
||||||
|
{0x12DD, "pic1_28.dds"},
|
||||||
|
{0x12DE, "pic1_29.dds"},
|
||||||
|
{0x12DF, "pic1_30.dds"},
|
||||||
|
{0x1400, "trophy/trophy00.trp"},
|
||||||
|
{0x1401, "trophy/trophy01.trp"},
|
||||||
|
{0x1402, "trophy/trophy02.trp"},
|
||||||
|
{0x1403, "trophy/trophy03.trp"},
|
||||||
|
{0x1404, "trophy/trophy04.trp"},
|
||||||
|
{0x1405, "trophy/trophy05.trp"},
|
||||||
|
{0x1406, "trophy/trophy06.trp"},
|
||||||
|
{0x1407, "trophy/trophy07.trp"},
|
||||||
|
{0x1408, "trophy/trophy08.trp"},
|
||||||
|
{0x1409, "trophy/trophy09.trp"},
|
||||||
|
{0x140A, "trophy/trophy10.trp"},
|
||||||
|
{0x140B, "trophy/trophy11.trp"},
|
||||||
|
{0x140C, "trophy/trophy12.trp"},
|
||||||
|
{0x140D, "trophy/trophy13.trp"},
|
||||||
|
{0x140E, "trophy/trophy14.trp"},
|
||||||
|
{0x140F, "trophy/trophy15.trp"},
|
||||||
|
{0x1410, "trophy/trophy16.trp"},
|
||||||
|
{0x1411, "trophy/trophy17.trp"},
|
||||||
|
{0x1412, "trophy/trophy18.trp"},
|
||||||
|
{0x1413, "trophy/trophy19.trp"},
|
||||||
|
{0x1414, "trophy/trophy20.trp"},
|
||||||
|
{0x1415, "trophy/trophy21.trp"},
|
||||||
|
{0x1416, "trophy/trophy22.trp"},
|
||||||
|
{0x1417, "trophy/trophy23.trp"},
|
||||||
|
{0x1418, "trophy/trophy24.trp"},
|
||||||
|
{0x1419, "trophy/trophy25.trp"},
|
||||||
|
{0x141A, "trophy/trophy26.trp"},
|
||||||
|
{0x141B, "trophy/trophy27.trp"},
|
||||||
|
{0x141C, "trophy/trophy28.trp"},
|
||||||
|
{0x141D, "trophy/trophy29.trp"},
|
||||||
|
{0x141E, "trophy/trophy30.trp"},
|
||||||
|
{0x141F, "trophy/trophy31.trp"},
|
||||||
|
{0x1420, "trophy/trophy32.trp"},
|
||||||
|
{0x1421, "trophy/trophy33.trp"},
|
||||||
|
{0x1422, "trophy/trophy34.trp"},
|
||||||
|
{0x1423, "trophy/trophy35.trp"},
|
||||||
|
{0x1424, "trophy/trophy36.trp"},
|
||||||
|
{0x1425, "trophy/trophy37.trp"},
|
||||||
|
{0x1426, "trophy/trophy38.trp"},
|
||||||
|
{0x1427, "trophy/trophy39.trp"},
|
||||||
|
{0x1428, "trophy/trophy40.trp"},
|
||||||
|
{0x1429, "trophy/trophy41.trp"},
|
||||||
|
{0x142A, "trophy/trophy42.trp"},
|
||||||
|
{0x142B, "trophy/trophy43.trp"},
|
||||||
|
{0x142C, "trophy/trophy44.trp"},
|
||||||
|
{0x142D, "trophy/trophy45.trp"},
|
||||||
|
{0x142E, "trophy/trophy46.trp"},
|
||||||
|
{0x142F, "trophy/trophy47.trp"},
|
||||||
|
{0x1430, "trophy/trophy48.trp"},
|
||||||
|
{0x1431, "trophy/trophy49.trp"},
|
||||||
|
{0x1432, "trophy/trophy50.trp"},
|
||||||
|
{0x1433, "trophy/trophy51.trp"},
|
||||||
|
{0x1434, "trophy/trophy52.trp"},
|
||||||
|
{0x1435, "trophy/trophy53.trp"},
|
||||||
|
{0x1436, "trophy/trophy54.trp"},
|
||||||
|
{0x1437, "trophy/trophy55.trp"},
|
||||||
|
{0x1438, "trophy/trophy56.trp"},
|
||||||
|
{0x1439, "trophy/trophy57.trp"},
|
||||||
|
{0x143A, "trophy/trophy58.trp"},
|
||||||
|
{0x143B, "trophy/trophy59.trp"},
|
||||||
|
{0x143C, "trophy/trophy60.trp"},
|
||||||
|
{0x143D, "trophy/trophy61.trp"},
|
||||||
|
{0x143E, "trophy/trophy62.trp"},
|
||||||
|
{0x143F, "trophy/trophy63.trp"},
|
||||||
|
{0x1440, "trophy/trophy64.trp"},
|
||||||
|
{0x1441, "trophy/trophy65.trp"},
|
||||||
|
{0x1442, "trophy/trophy66.trp"},
|
||||||
|
{0x1443, "trophy/trophy67.trp"},
|
||||||
|
{0x1444, "trophy/trophy68.trp"},
|
||||||
|
{0x1445, "trophy/trophy69.trp"},
|
||||||
|
{0x1446, "trophy/trophy70.trp"},
|
||||||
|
{0x1447, "trophy/trophy71.trp"},
|
||||||
|
{0x1448, "trophy/trophy72.trp"},
|
||||||
|
{0x1449, "trophy/trophy73.trp"},
|
||||||
|
{0x144A, "trophy/trophy74.trp"},
|
||||||
|
{0x144B, "trophy/trophy75.trp"},
|
||||||
|
{0x144C, "trophy/trophy76.trp"},
|
||||||
|
{0x144D, "trophy/trophy77.trp"},
|
||||||
|
{0x144E, "trophy/trophy78.trp"},
|
||||||
|
{0x144F, "trophy/trophy79.trp"},
|
||||||
|
{0x1450, "trophy/trophy80.trp"},
|
||||||
|
{0x1451, "trophy/trophy81.trp"},
|
||||||
|
{0x1452, "trophy/trophy82.trp"},
|
||||||
|
{0x1453, "trophy/trophy83.trp"},
|
||||||
|
{0x1454, "trophy/trophy84.trp"},
|
||||||
|
{0x1455, "trophy/trophy85.trp"},
|
||||||
|
{0x1456, "trophy/trophy86.trp"},
|
||||||
|
{0x1457, "trophy/trophy87.trp"},
|
||||||
|
{0x1458, "trophy/trophy88.trp"},
|
||||||
|
{0x1459, "trophy/trophy89.trp"},
|
||||||
|
{0x145A, "trophy/trophy90.trp"},
|
||||||
|
{0x145B, "trophy/trophy91.trp"},
|
||||||
|
{0x145C, "trophy/trophy92.trp"},
|
||||||
|
{0x145D, "trophy/trophy93.trp"},
|
||||||
|
{0x145E, "trophy/trophy94.trp"},
|
||||||
|
{0x145F, "trophy/trophy95.trp"},
|
||||||
|
{0x1460, "trophy/trophy96.trp"},
|
||||||
|
{0x1461, "trophy/trophy97.trp"},
|
||||||
|
{0x1462, "trophy/trophy98.trp"},
|
||||||
|
{0x1463, "trophy/trophy99.trp"},
|
||||||
|
{0x1600, "keymap_rp/001.png"},
|
||||||
|
{0x1601, "keymap_rp/002.png"},
|
||||||
|
{0x1602, "keymap_rp/003.png"},
|
||||||
|
{0x1603, "keymap_rp/004.png"},
|
||||||
|
{0x1604, "keymap_rp/005.png"},
|
||||||
|
{0x1605, "keymap_rp/006.png"},
|
||||||
|
{0x1606, "keymap_rp/007.png"},
|
||||||
|
{0x1607, "keymap_rp/008.png"},
|
||||||
|
{0x1608, "keymap_rp/009.png"},
|
||||||
|
{0x1609, "keymap_rp/010.png"},
|
||||||
|
{0x1610, "keymap_rp/00/001.png"},
|
||||||
|
{0x1611, "keymap_rp/00/002.png"},
|
||||||
|
{0x1612, "keymap_rp/00/003.png"},
|
||||||
|
{0x1613, "keymap_rp/00/004.png"},
|
||||||
|
{0x1614, "keymap_rp/00/005.png"},
|
||||||
|
{0x1615, "keymap_rp/00/006.png"},
|
||||||
|
{0x1616, "keymap_rp/00/007.png"},
|
||||||
|
{0x1617, "keymap_rp/00/008.png"},
|
||||||
|
{0x1618, "keymap_rp/00/009.png"},
|
||||||
|
{0x1619, "keymap_rp/00/010.png"},
|
||||||
|
{0x1620, "keymap_rp/01/001.png"},
|
||||||
|
{0x1621, "keymap_rp/01/002.png"},
|
||||||
|
{0x1622, "keymap_rp/01/003.png"},
|
||||||
|
{0x1623, "keymap_rp/01/004.png"},
|
||||||
|
{0x1624, "keymap_rp/01/005.png"},
|
||||||
|
{0x1625, "keymap_rp/01/006.png"},
|
||||||
|
{0x1626, "keymap_rp/01/007.png"},
|
||||||
|
{0x1627, "keymap_rp/01/008.png"},
|
||||||
|
{0x1628, "keymap_rp/01/009.png"},
|
||||||
|
{0x1629, "keymap_rp/01/010.png"},
|
||||||
|
{0x1630, "keymap_rp/02/001.png"},
|
||||||
|
{0x1631, "keymap_rp/02/002.png"},
|
||||||
|
{0x1632, "keymap_rp/02/003.png"},
|
||||||
|
{0x1633, "keymap_rp/02/004.png"},
|
||||||
|
{0x1634, "keymap_rp/02/005.png"},
|
||||||
|
{0x1635, "keymap_rp/02/006.png"},
|
||||||
|
{0x1636, "keymap_rp/02/007.png"},
|
||||||
|
{0x1637, "keymap_rp/02/008.png"},
|
||||||
|
{0x1638, "keymap_rp/02/009.png"},
|
||||||
|
{0x1639, "keymap_rp/02/010.png"},
|
||||||
|
{0x1640, "keymap_rp/03/001.png"},
|
||||||
|
{0x1641, "keymap_rp/03/002.png"},
|
||||||
|
{0x1642, "keymap_rp/03/003.png"},
|
||||||
|
{0x1643, "keymap_rp/03/004.png"},
|
||||||
|
{0x1644, "keymap_rp/03/005.png"},
|
||||||
|
{0x1645, "keymap_rp/03/006.png"},
|
||||||
|
{0x1646, "keymap_rp/03/007.png"},
|
||||||
|
{0x1647, "keymap_rp/03/008.png"},
|
||||||
|
{0x1648, "keymap_rp/03/0010.png"},
|
||||||
|
{0x1650, "keymap_rp/04/001.png"},
|
||||||
|
{0x1651, "keymap_rp/04/002.png"},
|
||||||
|
{0x1652, "keymap_rp/04/003.png"},
|
||||||
|
{0x1653, "keymap_rp/04/004.png"},
|
||||||
|
{0x1654, "keymap_rp/04/005.png"},
|
||||||
|
{0x1655, "keymap_rp/04/006.png"},
|
||||||
|
{0x1656, "keymap_rp/04/007.png"},
|
||||||
|
{0x1657, "keymap_rp/04/008.png"},
|
||||||
|
{0x1658, "keymap_rp/04/009.png"},
|
||||||
|
{0x1659, "keymap_rp/04/010.png"},
|
||||||
|
{0x1660, "keymap_rp/05/001.png"},
|
||||||
|
{0x1661, "keymap_rp/05/002.png"},
|
||||||
|
{0x1662, "keymap_rp/05/003.png"},
|
||||||
|
{0x1663, "keymap_rp/05/004.png"},
|
||||||
|
{0x1664, "keymap_rp/05/005.png"},
|
||||||
|
{0x1665, "keymap_rp/05/006.png"},
|
||||||
|
{0x1666, "keymap_rp/05/007.png"},
|
||||||
|
{0x1667, "keymap_rp/05/008.png"},
|
||||||
|
{0x1668, "keymap_rp/05/009.png"},
|
||||||
|
{0x1669, "keymap_rp/05/010.png"},
|
||||||
|
{0x1670, "keymap_rp/06/001.png"},
|
||||||
|
{0x1671, "keymap_rp/06/002.png"},
|
||||||
|
{0x1672, "keymap_rp/06/003.png"},
|
||||||
|
{0x1673, "keymap_rp/06/004.png"},
|
||||||
|
{0x1674, "keymap_rp/06/005.png"},
|
||||||
|
{0x1675, "keymap_rp/06/006.png"},
|
||||||
|
{0x1676, "keymap_rp/06/007.png"},
|
||||||
|
{0x1677, "keymap_rp/06/008.png"},
|
||||||
|
{0x1678, "keymap_rp/06/009.png"},
|
||||||
|
{0x1679, "keymap_rp/06/010.png"},
|
||||||
|
{0x1680, "keymap_rp/07/001.png"},
|
||||||
|
{0x1681, "keymap_rp/07/002.png"},
|
||||||
|
{0x1682, "keymap_rp/07/003.png"},
|
||||||
|
{0x1683, "keymap_rp/07/004.png"},
|
||||||
|
{0x1684, "keymap_rp/07/005.png"},
|
||||||
|
{0x1685, "keymap_rp/07/006.png"},
|
||||||
|
{0x1686, "keymap_rp/07/007.png"},
|
||||||
|
{0x1687, "keymap_rp/07/008.png"},
|
||||||
|
{0x1688, "keymap_rp/07/009.png"},
|
||||||
|
{0x1689, "keymap_rp/07/010.png"},
|
||||||
|
{0x1690, "keymap_rp/08/001.png"},
|
||||||
|
{0x1691, "keymap_rp/08/002.png"},
|
||||||
|
{0x1692, "keymap_rp/08/003.png"},
|
||||||
|
{0x1693, "keymap_rp/08/004.png"},
|
||||||
|
{0x1694, "keymap_rp/08/005.png"},
|
||||||
|
{0x1695, "keymap_rp/08/006.png"},
|
||||||
|
{0x1696, "keymap_rp/08/007.png"},
|
||||||
|
{0x1697, "keymap_rp/08/008.png"},
|
||||||
|
{0x1698, "keymap_rp/08/009.png"},
|
||||||
|
{0x1699, "keymap_rp/08/010.png"},
|
||||||
|
{0x16A0, "keymap_rp/09/001.png"},
|
||||||
|
{0x16A1, "keymap_rp/09/002.png"},
|
||||||
|
{0x16A2, "keymap_rp/09/003.png"},
|
||||||
|
{0x16A3, "keymap_rp/09/004.png"},
|
||||||
|
{0x16A4, "keymap_rp/09/005.png"},
|
||||||
|
{0x16A5, "keymap_rp/09/006.png"},
|
||||||
|
{0x16A6, "keymap_rp/09/007.png"},
|
||||||
|
{0x16A7, "keymap_rp/09/008.png"},
|
||||||
|
{0x16A8, "keymap_rp/09/009.png"},
|
||||||
|
{0x16A9, "keymap_rp/09/010.png"},
|
||||||
|
{0x16B0, "keymap_rp/10/001.png"},
|
||||||
|
{0x16B1, "keymap_rp/10/002.png"},
|
||||||
|
{0x16B2, "keymap_rp/10/003.png"},
|
||||||
|
{0x16B3, "keymap_rp/10/004.png"},
|
||||||
|
{0x16B4, "keymap_rp/10/005.png"},
|
||||||
|
{0x16B5, "keymap_rp/10/006.png"},
|
||||||
|
{0x16B6, "keymap_rp/10/007.png"},
|
||||||
|
{0x16B7, "keymap_rp/10/008.png"},
|
||||||
|
{0x16B8, "keymap_rp/10/009.png"},
|
||||||
|
{0x16B9, "keymap_rp/10/010.png"},
|
||||||
|
{0x16C0, "keymap_rp/11/001.png"},
|
||||||
|
{0x16C1, "keymap_rp/11/002.png"},
|
||||||
|
{0x16C2, "keymap_rp/11/003.png"},
|
||||||
|
{0x16C3, "keymap_rp/11/004.png"},
|
||||||
|
{0x16C4, "keymap_rp/11/005.png"},
|
||||||
|
{0x16C5, "keymap_rp/11/006.png"},
|
||||||
|
{0x16C6, "keymap_rp/11/007.png"},
|
||||||
|
{0x16C7, "keymap_rp/11/008.png"},
|
||||||
|
{0x16C8, "keymap_rp/11/009.png"},
|
||||||
|
{0x16C9, "keymap_rp/11/010.png"},
|
||||||
|
{0x16D0, "keymap_rp/12/001.png"},
|
||||||
|
{0x16D1, "keymap_rp/12/002.png"},
|
||||||
|
{0x16D2, "keymap_rp/12/003.png"},
|
||||||
|
{0x16D3, "keymap_rp/12/004.png"},
|
||||||
|
{0x16D4, "keymap_rp/12/005.png"},
|
||||||
|
{0x16D5, "keymap_rp/12/006.png"},
|
||||||
|
{0x16D6, "keymap_rp/12/007.png"},
|
||||||
|
{0x16D7, "keymap_rp/12/008.png"},
|
||||||
|
{0x16D8, "keymap_rp/12/009.png"},
|
||||||
|
{0x16D9, "keymap_rp/12/010.png"},
|
||||||
|
{0x16E0, "keymap_rp/13/001.png"},
|
||||||
|
{0x16E1, "keymap_rp/13/002.png"},
|
||||||
|
{0x16E2, "keymap_rp/13/003.png"},
|
||||||
|
{0x16E3, "keymap_rp/13/004.png"},
|
||||||
|
{0x16E4, "keymap_rp/13/005.png"},
|
||||||
|
{0x16E5, "keymap_rp/13/006.png"},
|
||||||
|
{0x16E6, "keymap_rp/13/007.png"},
|
||||||
|
{0x16E7, "keymap_rp/13/008.png"},
|
||||||
|
{0x16E8, "keymap_rp/13/009.png"},
|
||||||
|
{0x16E9, "keymap_rp/13/010.png"},
|
||||||
|
{0x16F0, "keymap_rp/14/001.png"},
|
||||||
|
{0x16F1, "keymap_rp/14/002.png"},
|
||||||
|
{0x16F2, "keymap_rp/14/003.png"},
|
||||||
|
{0x16F3, "keymap_rp/14/004.png"},
|
||||||
|
{0x16F4, "keymap_rp/14/005.png"},
|
||||||
|
{0x16F5, "keymap_rp/14/006.png"},
|
||||||
|
{0x16F6, "keymap_rp/14/007.png"},
|
||||||
|
{0x16F7, "keymap_rp/14/008.png"},
|
||||||
|
{0x16F8, "keymap_rp/14/009.png"},
|
||||||
|
{0x16F9, "keymap_rp/14/010.png"},
|
||||||
|
{0x1700, "keymap_rp/15/001.png"},
|
||||||
|
{0x1701, "keymap_rp/15/002.png"},
|
||||||
|
{0x1702, "keymap_rp/15/003.png"},
|
||||||
|
{0x1703, "keymap_rp/15/004.png"},
|
||||||
|
{0x1704, "keymap_rp/15/005.png"},
|
||||||
|
{0x1705, "keymap_rp/15/006.png"},
|
||||||
|
{0x1706, "keymap_rp/15/007.png"},
|
||||||
|
{0x1707, "keymap_rp/15/008.png"},
|
||||||
|
{0x1708, "keymap_rp/15/009.png"},
|
||||||
|
{0x1709, "keymap_rp/15/010.png"},
|
||||||
|
{0x1710, "keymap_rp/16/001.png"},
|
||||||
|
{0x1711, "keymap_rp/16/002.png"},
|
||||||
|
{0x1712, "keymap_rp/16/003.png"},
|
||||||
|
{0x1713, "keymap_rp/16/004.png"},
|
||||||
|
{0x1714, "keymap_rp/16/005.png"},
|
||||||
|
{0x1715, "keymap_rp/16/006.png"},
|
||||||
|
{0x1716, "keymap_rp/16/007.png"},
|
||||||
|
{0x1717, "keymap_rp/16/008.png"},
|
||||||
|
{0x1718, "keymap_rp/16/009.png"},
|
||||||
|
{0x1719, "keymap_rp/16/010.png"},
|
||||||
|
{0x1720, "keymap_rp/17/001.png"},
|
||||||
|
{0x1721, "keymap_rp/17/002.png"},
|
||||||
|
{0x1722, "keymap_rp/17/003.png"},
|
||||||
|
{0x1723, "keymap_rp/17/004.png"},
|
||||||
|
{0x1724, "keymap_rp/17/005.png"},
|
||||||
|
{0x1725, "keymap_rp/17/006.png"},
|
||||||
|
{0x1726, "keymap_rp/17/007.png"},
|
||||||
|
{0x1727, "keymap_rp/17/008.png"},
|
||||||
|
{0x1728, "keymap_rp/17/009.png"},
|
||||||
|
{0x1729, "keymap_rp/17/010.png"},
|
||||||
|
{0x1730, "keymap_rp/18/001.png"},
|
||||||
|
{0x1731, "keymap_rp/18/002.png"},
|
||||||
|
{0x1732, "keymap_rp/18/003.png"},
|
||||||
|
{0x1733, "keymap_rp/18/004.png"},
|
||||||
|
{0x1734, "keymap_rp/18/005.png"},
|
||||||
|
{0x1735, "keymap_rp/18/006.png"},
|
||||||
|
{0x1736, "keymap_rp/18/007.png"},
|
||||||
|
{0x1737, "keymap_rp/18/008.png"},
|
||||||
|
{0x1738, "keymap_rp/18/009.png"},
|
||||||
|
{0x1739, "keymap_rp/18/010.png"},
|
||||||
|
{0x1740, "keymap_rp/19/001.png"},
|
||||||
|
{0x1741, "keymap_rp/19/002.png"},
|
||||||
|
{0x1742, "keymap_rp/19/003.png"},
|
||||||
|
{0x1743, "keymap_rp/19/004.png"},
|
||||||
|
{0x1744, "keymap_rp/19/005.png"},
|
||||||
|
{0x1745, "keymap_rp/19/006.png"},
|
||||||
|
{0x1746, "keymap_rp/19/007.png"},
|
||||||
|
{0x1747, "keymap_rp/19/008.png"},
|
||||||
|
{0x1748, "keymap_rp/19/009.png"},
|
||||||
|
{0x1749, "keymap_rp/19/010.png"},
|
||||||
|
{0x1750, "keymap_rp/20/001.png"},
|
||||||
|
{0x1751, "keymap_rp/20/002.png"},
|
||||||
|
{0x1752, "keymap_rp/20/003.png"},
|
||||||
|
{0x1753, "keymap_rp/20/004.png"},
|
||||||
|
{0x1754, "keymap_rp/20/005.png"},
|
||||||
|
{0x1755, "keymap_rp/20/006.png"},
|
||||||
|
{0x1756, "keymap_rp/20/007.png"},
|
||||||
|
{0x1757, "keymap_rp/20/008.png"},
|
||||||
|
{0x1758, "keymap_rp/20/009.png"},
|
||||||
|
{0x1759, "keymap_rp/20/010.png"},
|
||||||
|
{0x1760, "keymap_rp/21/001.png"},
|
||||||
|
{0x1761, "keymap_rp/21/002.png"},
|
||||||
|
{0x1762, "keymap_rp/21/003.png"},
|
||||||
|
{0x1763, "keymap_rp/21/004.png"},
|
||||||
|
{0x1764, "keymap_rp/21/005.png"},
|
||||||
|
{0x1765, "keymap_rp/21/006.png"},
|
||||||
|
{0x1766, "keymap_rp/21/007.png"},
|
||||||
|
{0x1767, "keymap_rp/21/008.png"},
|
||||||
|
{0x1768, "keymap_rp/21/009.png"},
|
||||||
|
{0x1769, "keymap_rp/21/010.png"},
|
||||||
|
{0x1770, "keymap_rp/22/001.png"},
|
||||||
|
{0x1771, "keymap_rp/22/002.png"},
|
||||||
|
{0x1772, "keymap_rp/22/003.png"},
|
||||||
|
{0x1773, "keymap_rp/22/004.png"},
|
||||||
|
{0x1774, "keymap_rp/22/005.png"},
|
||||||
|
{0x1775, "keymap_rp/22/006.png"},
|
||||||
|
{0x1776, "keymap_rp/22/007.png"},
|
||||||
|
{0x1777, "keymap_rp/22/008.png"},
|
||||||
|
{0x1778, "keymap_rp/22/009.png"},
|
||||||
|
{0x1779, "keymap_rp/22/010.png"},
|
||||||
|
{0x1780, "keymap_rp/23/001.png"},
|
||||||
|
{0x1781, "keymap_rp/23/002.png"},
|
||||||
|
{0x1782, "keymap_rp/23/003.png"},
|
||||||
|
{0x1783, "keymap_rp/23/004.png"},
|
||||||
|
{0x1784, "keymap_rp/23/005.png"},
|
||||||
|
{0x1785, "keymap_rp/23/006.png"},
|
||||||
|
{0x1786, "keymap_rp/23/007.png"},
|
||||||
|
{0x1787, "keymap_rp/23/008.png"},
|
||||||
|
{0x1788, "keymap_rp/23/009.png"},
|
||||||
|
{0x1789, "keymap_rp/23/010.png"},
|
||||||
|
{0x1790, "keymap_rp/24/001.png"},
|
||||||
|
{0x1791, "keymap_rp/24/002.png"},
|
||||||
|
{0x1792, "keymap_rp/24/003.png"},
|
||||||
|
{0x1793, "keymap_rp/24/004.png"},
|
||||||
|
{0x1794, "keymap_rp/24/005.png"},
|
||||||
|
{0x1795, "keymap_rp/24/006.png"},
|
||||||
|
{0x1796, "keymap_rp/24/007.png"},
|
||||||
|
{0x1797, "keymap_rp/24/008.png"},
|
||||||
|
{0x1798, "keymap_rp/24/009.png"},
|
||||||
|
{0x1799, "keymap_rp/24/010.png"},
|
||||||
|
{0x17A0, "keymap_rp/25/001.png"},
|
||||||
|
{0x17A1, "keymap_rp/25/002.png"},
|
||||||
|
{0x17A2, "keymap_rp/25/003.png"},
|
||||||
|
{0x17A3, "keymap_rp/25/004.png"},
|
||||||
|
{0x17A4, "keymap_rp/25/005.png"},
|
||||||
|
{0x17A5, "keymap_rp/25/006.png"},
|
||||||
|
{0x17A6, "keymap_rp/25/007.png"},
|
||||||
|
{0x17A7, "keymap_rp/25/008.png"},
|
||||||
|
{0x17A8, "keymap_rp/25/009.png"},
|
||||||
|
{0x17A9, "keymap_rp/25/010.png"},
|
||||||
|
{0x17B0, "keymap_rp/26/001.png"},
|
||||||
|
{0x17B1, "keymap_rp/26/002.png"},
|
||||||
|
{0x17B2, "keymap_rp/26/003.png"},
|
||||||
|
{0x17B3, "keymap_rp/26/004.png"},
|
||||||
|
{0x17B4, "keymap_rp/26/005.png"},
|
||||||
|
{0x17B5, "keymap_rp/26/006.png"},
|
||||||
|
{0x17B6, "keymap_rp/26/007.png"},
|
||||||
|
{0x17B7, "keymap_rp/26/008.png"},
|
||||||
|
{0x17B8, "keymap_rp/26/009.png"},
|
||||||
|
{0x17B9, "keymap_rp/26/010.png"},
|
||||||
|
{0x17C0, "keymap_rp/27/001.png"},
|
||||||
|
{0x17C1, "keymap_rp/27/002.png"},
|
||||||
|
{0x17C2, "keymap_rp/27/003.png"},
|
||||||
|
{0x17C3, "keymap_rp/27/004.png"},
|
||||||
|
{0x17C4, "keymap_rp/27/005.png"},
|
||||||
|
{0x17C5, "keymap_rp/27/006.png"},
|
||||||
|
{0x17C6, "keymap_rp/27/007.png"},
|
||||||
|
{0x17C7, "keymap_rp/27/008.png"},
|
||||||
|
{0x17C8, "keymap_rp/27/009.png"},
|
||||||
|
{0x17C9, "keymap_rp/27/010.png"},
|
||||||
|
{0x17D0, "keymap_rp/28/001.png"},
|
||||||
|
{0x17D1, "keymap_rp/28/002.png"},
|
||||||
|
{0x17D2, "keymap_rp/28/003.png"},
|
||||||
|
{0x17D3, "keymap_rp/28/004.png"},
|
||||||
|
{0x17D4, "keymap_rp/28/005.png"},
|
||||||
|
{0x17D5, "keymap_rp/28/006.png"},
|
||||||
|
{0x17D6, "keymap_rp/28/007.png"},
|
||||||
|
{0x17D7, "keymap_rp/28/008.png"},
|
||||||
|
{0x17D8, "keymap_rp/28/009.png"},
|
||||||
|
{0x17D9, "keymap_rp/28/010.png"},
|
||||||
|
{0x17E0, "keymap_rp/29/001.png"},
|
||||||
|
{0x17E1, "keymap_rp/29/002.png"},
|
||||||
|
{0x17E2, "keymap_rp/29/003.png"},
|
||||||
|
{0x17E3, "keymap_rp/29/004.png"},
|
||||||
|
{0x17E4, "keymap_rp/29/005.png"},
|
||||||
|
{0x17E5, "keymap_rp/29/006.png"},
|
||||||
|
{0x17E6, "keymap_rp/29/007.png"},
|
||||||
|
{0x17E7, "keymap_rp/29/008.png"},
|
||||||
|
{0x17E8, "keymap_rp/29/009.png"},
|
||||||
|
{0x17E9, "keymap_rp/29/010.png"},
|
||||||
|
{0x17F0, "keymap_rp/30/001.png"},
|
||||||
|
{0x17F1, "keymap_rp/30/002.png"},
|
||||||
|
{0x17F2, "keymap_rp/30/003.png"},
|
||||||
|
{0x17F3, "keymap_rp/30/004.png"},
|
||||||
|
{0x17F4, "keymap_rp/30/005.png"},
|
||||||
|
{0x17F5, "keymap_rp/30/006.png"},
|
||||||
|
{0x17F6, "keymap_rp/30/007.png"},
|
||||||
|
{0x17F7, "keymap_rp/30/008.png"},
|
||||||
|
{0x17F8, "keymap_rp/30/009.png"},
|
||||||
|
{0x17F9, "keymap_rp/30/010.png"},
|
||||||
|
}};
|
||||||
|
|
||||||
|
std::string_view GetEntryNameByType(u32 type) {
|
||||||
|
const auto key = PkgEntryValue{type};
|
||||||
|
const auto it = std::ranges::lower_bound(PkgEntries, key);
|
||||||
|
if (it != PkgEntries.end() && it->type == type) {
|
||||||
|
return it->name;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
10
src/core/file_format/pkg_type.h
Normal file
10
src/core/file_format/pkg_type.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string_view>
|
||||||
|
#include "common/types.h"
|
||||||
|
|
||||||
|
/// Retrieves the PKG entry name from its type identifier.
|
||||||
|
std::string_view GetEntryNameByType(u32 type);
|
|
@ -1,25 +1,10 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "common/aes.h"
|
|
||||||
#include "common/config.h"
|
#include "common/config.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
#include "core/file_format/trp.h"
|
#include "trp.h"
|
||||||
|
|
||||||
static void DecryptEFSM(std::span<u8, 16> trophyKey, std::span<u8, 16> NPcommID,
|
|
||||||
std::span<u8, 16> efsmIv, std::span<u8> ciphertext,
|
|
||||||
std::span<u8> decrypted) {
|
|
||||||
// Step 1: Encrypt NPcommID
|
|
||||||
std::array<u8, 16> trophyIv{};
|
|
||||||
std::array<u8, 16> trpKey;
|
|
||||||
aes::encrypt_cbc(NPcommID.data(), NPcommID.size(), trophyKey.data(), trophyKey.size(),
|
|
||||||
trophyIv.data(), trpKey.data(), trpKey.size(), false);
|
|
||||||
|
|
||||||
// Step 2: Decrypt EFSM
|
|
||||||
aes::decrypt_cbc(ciphertext.data(), ciphertext.size(), trpKey.data(), trpKey.size(),
|
|
||||||
efsmIv.data(), decrypted.data(), decrypted.size(), nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
TRP::TRP() = default;
|
TRP::TRP() = default;
|
||||||
TRP::~TRP() = default;
|
TRP::~TRP() = default;
|
||||||
|
@ -69,7 +54,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<u8, 16> user_key{};
|
std::array<CryptoPP::byte, 16> user_key{};
|
||||||
hexToBytes(user_key_str.c_str(), user_key.data());
|
hexToBytes(user_key_str.c_str(), user_key.data());
|
||||||
|
|
||||||
for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) {
|
for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) {
|
||||||
|
@ -130,7 +115,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
file.Read(ESFM);
|
file.Read(ESFM);
|
||||||
DecryptEFSM(user_key, np_comm_id, esfmIv, ESFM, XML); // decrypt
|
crypto.decryptEFSM(user_key, np_comm_id, esfmIv, ESFM, XML); // decrypt
|
||||||
removePadding(XML);
|
removePadding(XML);
|
||||||
std::string xml_name = entry.entry_name;
|
std::string xml_name = entry.entry_name;
|
||||||
size_t pos = xml_name.find("ESFM");
|
size_t pos = xml_name.find("ESFM");
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
#include "common/io_file.h"
|
#include "common/io_file.h"
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
|
#include "core/crypto/crypto.h"
|
||||||
|
|
||||||
struct TrpHeader {
|
struct TrpHeader {
|
||||||
u32_be magic; // (0xDCA24D00)
|
u32_be magic; // (0xDCA24D00)
|
||||||
|
@ -36,6 +37,7 @@ public:
|
||||||
void GetNPcommID(const std::filesystem::path& trophyPath, int index);
|
void GetNPcommID(const std::filesystem::path& trophyPath, int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Crypto crypto;
|
||||||
std::vector<u8> NPcommID = std::vector<u8>(12);
|
std::vector<u8> NPcommID = std::vector<u8>(12);
|
||||||
std::array<u8, 16> np_comm_id{};
|
std::array<u8, 16> np_comm_id{};
|
||||||
std::array<u8, 16> esfmIv{};
|
std::array<u8, 16> esfmIv{};
|
||||||
|
|
|
@ -70,10 +70,6 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea
|
||||||
std::filesystem::path host_path = mount->host_path / rel_path;
|
std::filesystem::path host_path = mount->host_path / rel_path;
|
||||||
std::filesystem::path patch_path = mount->host_path;
|
std::filesystem::path patch_path = mount->host_path;
|
||||||
patch_path += "-UPDATE";
|
patch_path += "-UPDATE";
|
||||||
if (!std::filesystem::exists(patch_path)) {
|
|
||||||
patch_path = mount->host_path;
|
|
||||||
patch_path += "-patch";
|
|
||||||
}
|
|
||||||
patch_path /= rel_path;
|
patch_path /= rel_path;
|
||||||
|
|
||||||
if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) &&
|
if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) &&
|
||||||
|
|
|
@ -191,7 +191,6 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
|
||||||
case OrbisAudioOutPort::Main:
|
case OrbisAudioOutPort::Main:
|
||||||
case OrbisAudioOutPort::Bgm:
|
case OrbisAudioOutPort::Bgm:
|
||||||
case OrbisAudioOutPort::Voice:
|
case OrbisAudioOutPort::Voice:
|
||||||
case OrbisAudioOutPort::Audio3d:
|
|
||||||
state->output = 1;
|
state->output = 1;
|
||||||
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
||||||
break;
|
break;
|
||||||
|
@ -317,7 +316,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
||||||
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
||||||
}
|
}
|
||||||
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
||||||
(port_type != OrbisAudioOutPort::Audio3d && port_type != OrbisAudioOutPort::Aux)) {
|
(port_type != OrbisAudioOutPort::Aux)) {
|
||||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,15 +20,7 @@ class PortBackend;
|
||||||
constexpr s32 SCE_AUDIO_OUT_NUM_PORTS = 22;
|
constexpr s32 SCE_AUDIO_OUT_NUM_PORTS = 22;
|
||||||
constexpr s32 SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
constexpr s32 SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
||||||
|
|
||||||
enum class OrbisAudioOutPort {
|
enum class OrbisAudioOutPort { Main = 0, Bgm = 1, Voice = 2, Personal = 3, Padspk = 4, Aux = 127 };
|
||||||
Main = 0,
|
|
||||||
Bgm = 1,
|
|
||||||
Voice = 2,
|
|
||||||
Personal = 3,
|
|
||||||
Padspk = 4,
|
|
||||||
Audio3d = 126,
|
|
||||||
Aux = 127,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class OrbisAudioOutParamFormat : u32 {
|
enum class OrbisAudioOutParamFormat : u32 {
|
||||||
S16Mono = 0,
|
S16Mono = 0,
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 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 <SDL3/SDL_audio.h>
|
|
||||||
#include <magic_enum/magic_enum.hpp>
|
|
||||||
|
|
||||||
#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/audio/audioout_error.h"
|
|
||||||
#include "core/libraries/audio3d/audio3d.h"
|
#include "core/libraries/audio3d/audio3d.h"
|
||||||
#include "core/libraries/audio3d/audio3d_error.h"
|
#include "core/libraries/audio3d/audio3d_error.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
|
@ -15,577 +10,331 @@
|
||||||
|
|
||||||
namespace Libraries::Audio3d {
|
namespace Libraries::Audio3d {
|
||||||
|
|
||||||
static constexpr u32 AUDIO3D_SAMPLE_RATE = 48000;
|
int PS4_SYSV_ABI sceAudio3dInitialize(s64 iReserved) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "iReserved = {}", iReserved);
|
||||||
static constexpr AudioOut::OrbisAudioOutParamFormat AUDIO3D_OUTPUT_FORMAT =
|
return ORBIS_OK;
|
||||||
AudioOut::OrbisAudioOutParamFormat::S16Stereo;
|
|
||||||
static constexpr u32 AUDIO3D_OUTPUT_NUM_CHANNELS = 2;
|
|
||||||
static constexpr u32 AUDIO3D_OUTPUT_BUFFER_FRAMES = 0x100;
|
|
||||||
|
|
||||||
static std::unique_ptr<Audio3dState> state;
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(const s32 handle) {
|
|
||||||
LOG_INFO(Lib_Audio3d, "called, handle = {}", handle);
|
|
||||||
return AudioOut::sceAudioOutClose(handle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI
|
int PS4_SYSV_ABI sceAudio3dTerminate() {
|
||||||
sceAudio3dAudioOutOpen(const OrbisAudio3dPortId port_id, const OrbisUserServiceUserId user_id,
|
// TODO: When not initialized or some ports still open, return ORBIS_AUDIO3D_ERROR_NOT_READY
|
||||||
s32 type, const s32 index, const u32 len, const u32 freq,
|
LOG_INFO(Lib_Audio3d, "called");
|
||||||
const AudioOut::OrbisAudioOutParamExtendedInformation param) {
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* parameters) {
|
||||||
|
if (parameters == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "Invalid OpenParameters ptr");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters->size_this = sizeof(OrbisAudio3dOpenParameters);
|
||||||
|
parameters->granularity = 256;
|
||||||
|
parameters->rate = OrbisAudio3dRate::Rate48000;
|
||||||
|
parameters->max_objects = 512;
|
||||||
|
parameters->queue_depth = 2;
|
||||||
|
parameters->buffer_mode = OrbisAudio3dBufferMode::AdvanceAndPush;
|
||||||
|
parameters->num_beds = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId iUserId,
|
||||||
|
const OrbisAudio3dOpenParameters* pParameters,
|
||||||
|
OrbisAudio3dPortId* pId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "iUserId = {}", iUserId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortClose(OrbisAudio3dPortId uiPortId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId uiPortId,
|
||||||
|
OrbisAudio3dAttributeId uiAttributeId,
|
||||||
|
const void* pAttribute, size_t szAttribute) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiAttributeId = {}, szAttribute = {}", uiPortId,
|
||||||
|
uiAttributeId, szAttribute);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortFlush(OrbisAudio3dPortId uiPortId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId uiPortId) {
|
||||||
|
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId uiPortId, OrbisAudio3dBlocking eBlocking) {
|
||||||
|
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported(OrbisAudio3dPortId uiPortId,
|
||||||
|
OrbisAudio3dAttributeId* pCapabilities,
|
||||||
|
u32* pNumCapabilities) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId uiPortId, u32* pQueueLevel,
|
||||||
|
u32* pQueueAvailable) {
|
||||||
|
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId uiPortId, OrbisAudio3dObjectId* pId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dObjectUnreserve(OrbisAudio3dPortId uiPortId,
|
||||||
|
OrbisAudio3dObjectId uiObjectId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}", uiPortId, uiObjectId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId uiPortId,
|
||||||
|
OrbisAudio3dObjectId uiObjectId,
|
||||||
|
size_t szNumAttributes,
|
||||||
|
const OrbisAudio3dAttribute* pAttributeArray) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}, szNumAttributes = {}", uiPortId,
|
||||||
|
uiObjectId, szNumAttributes);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||||
|
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||||
|
u32 uiNumSamples) {
|
||||||
|
LOG_TRACE(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}", uiPortId,
|
||||||
|
uiNumChannels, uiNumSamples);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||||
|
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||||
|
u32 uiNumSamples, OrbisAudio3dOutputRoute eOutputRoute,
|
||||||
|
bool bRestricted) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}, bRestricted = {}",
|
||||||
|
uiPortId, uiNumChannels, uiNumSamples, bRestricted);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize(u32 uiNumSpeakers, bool bIs3d) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiNumSpeakers = {}, bIs3d = {}", uiNumSpeakers, bIs3d);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI
|
||||||
|
sceAudio3dCreateSpeakerArray(OrbisAudio3dSpeakerArrayHandle* pHandle,
|
||||||
|
const OrbisAudio3dSpeakerArrayParameters* pParameters) {
|
||||||
|
if (pHandle == nullptr || pParameters == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArray parameters");
|
||||||
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
LOG_INFO(Lib_Audio3d, "called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray(OrbisAudio3dSpeakerArrayHandle handle) {
|
||||||
|
if (handle == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||||
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
LOG_INFO(Lib_Audio3d, "called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients(OrbisAudio3dSpeakerArrayHandle handle,
|
||||||
|
OrbisAudio3dPosition pos, float fSpread,
|
||||||
|
float* pCoefficients,
|
||||||
|
u32 uiNumCoefficients) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "fSpread = {}, uiNumCoefficients = {}", fSpread, uiNumCoefficients);
|
||||||
|
if (handle == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||||
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2(OrbisAudio3dSpeakerArrayHandle handle,
|
||||||
|
OrbisAudio3dPosition pos, float fSpread,
|
||||||
|
float* pCoefficients,
|
||||||
|
u32 uiNumCoefficients, bool bHeightAware,
|
||||||
|
float fDownmixSpreadRadius) {
|
||||||
LOG_INFO(Lib_Audio3d,
|
LOG_INFO(Lib_Audio3d,
|
||||||
"called, port_id = {}, user_id = {}, type = {}, index = {}, len = {}, freq = {}",
|
"fSpread = {}, uiNumCoefficients = {}, bHeightAware = {}, fDownmixSpreadRadius = {}",
|
||||||
port_id, user_id, type, index, len, freq);
|
fSpread, uiNumCoefficients, bHeightAware, fDownmixSpreadRadius);
|
||||||
|
if (handle == nullptr) {
|
||||||
if (!state->ports.contains(port_id)) {
|
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len != state->ports[port_id].parameters.granularity) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "len != state->ports[port_id].parameters.granularity");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sceAudioOutOpen(user_id, static_cast<AudioOut::OrbisAudioOutPort>(type), index, len,
|
|
||||||
freq, param);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(const s32 handle, void* ptr) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called, handle = {}, ptr = {}", handle, ptr);
|
|
||||||
|
|
||||||
if (!ptr) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!ptr");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handle < 0 || (handle & 0xFFFF) > 25) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "handle < 0 || (handle & 0xFFFF) > 25");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AudioOut::sceAudioOutOutput(handle, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param,
|
|
||||||
const u32 num) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called, param = {}, num = {}", static_cast<void*>(param), num);
|
|
||||||
|
|
||||||
if (!param || !num) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!param || !num");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AudioOut::sceAudioOutOutputs(param, num);
|
|
||||||
}
|
|
||||||
|
|
||||||
static s32 PortQueueAudio(Port& port, const OrbisAudio3dPcm& pcm, const u32 num_channels) {
|
|
||||||
// Audio3d output is configured for stereo signed 16-bit PCM. Convert the data to match.
|
|
||||||
const SDL_AudioSpec src_spec = {
|
|
||||||
.format = pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? SDL_AUDIO_S16LE
|
|
||||||
: SDL_AUDIO_F32LE,
|
|
||||||
.channels = static_cast<int>(num_channels),
|
|
||||||
.freq = AUDIO3D_SAMPLE_RATE,
|
|
||||||
};
|
|
||||||
constexpr SDL_AudioSpec dst_spec = {
|
|
||||||
.format = SDL_AUDIO_S16LE,
|
|
||||||
.channels = AUDIO3D_OUTPUT_NUM_CHANNELS,
|
|
||||||
.freq = AUDIO3D_SAMPLE_RATE,
|
|
||||||
};
|
|
||||||
const auto src_size = pcm.num_samples *
|
|
||||||
(pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? 2 : 4) *
|
|
||||||
num_channels;
|
|
||||||
|
|
||||||
u8* dst_data;
|
|
||||||
int dst_len;
|
|
||||||
if (!SDL_ConvertAudioSamples(&src_spec, static_cast<u8*>(pcm.sample_buffer),
|
|
||||||
static_cast<int>(src_size), &dst_spec, &dst_data, &dst_len)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "SDL_ConvertAudioSamples failed: {}", SDL_GetError());
|
|
||||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
port.queue.emplace_back(AudioData{
|
|
||||||
.sample_buffer = dst_data,
|
|
||||||
.num_samples = pcm.num_samples,
|
|
||||||
});
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId uiPortId, OrbisUserServiceUserId userId,
|
||||||
const OrbisAudio3dFormat format, void* buffer,
|
s32 type, s32 index, u32 len, u32 freq, u32 param) {
|
||||||
const u32 num_samples) {
|
|
||||||
return sceAudio3dBedWrite2(port_id, num_channels, format, buffer, num_samples,
|
|
||||||
OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
|
||||||
const OrbisAudio3dFormat format, void* buffer,
|
|
||||||
const u32 num_samples,
|
|
||||||
const OrbisAudio3dOutputRoute output_route,
|
|
||||||
const bool restricted) {
|
|
||||||
LOG_DEBUG(
|
|
||||||
Lib_Audio3d,
|
|
||||||
"called, port_id = {}, num_channels = {}, format = {}, num_samples = {}, output_route "
|
|
||||||
"= {}, restricted = {}",
|
|
||||||
port_id, num_channels, magic_enum::enum_name(format), num_samples,
|
|
||||||
magic_enum::enum_name(output_route), restricted);
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output_route > OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "output_route > ORBIS_AUDIO3D_OUTPUT_BOTH");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format > OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "format > ORBIS_AUDIO3D_FORMAT_FLOAT");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num_channels != 2 && num_channels != 8) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "num_channels != 2 && num_channels != 8");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!buffer || !num_samples) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!buffer || !num_samples");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
|
||||||
if ((reinterpret_cast<uintptr_t>(buffer) & 3) != 0) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "buffer & 3 != 0");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
} else if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16) {
|
|
||||||
if ((reinterpret_cast<uintptr_t>(buffer) & 1) != 0) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "buffer & 1 != 0");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return PortQueueAudio(state->ports[port_id],
|
|
||||||
OrbisAudio3dPcm{
|
|
||||||
.format = format,
|
|
||||||
.sample_buffer = buffer,
|
|
||||||
.num_samples = num_samples,
|
|
||||||
},
|
|
||||||
num_channels);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called");
|
|
||||||
if (params) {
|
|
||||||
*params = OrbisAudio3dOpenParameters{
|
|
||||||
.size_this = 0x20,
|
|
||||||
.granularity = 0x100,
|
|
||||||
.rate = OrbisAudio3dRate::ORBIS_AUDIO3D_RATE_48000,
|
|
||||||
.max_objects = 512,
|
|
||||||
.queue_depth = 2,
|
|
||||||
.buffer_mode = OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(const s64 reserved) {
|
|
||||||
LOG_INFO(Lib_Audio3d, "called, reserved = {}", reserved);
|
|
||||||
|
|
||||||
if (reserved != 0) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "reserved != 0");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "already initialized");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
state = std::make_unique<Audio3dState>();
|
|
||||||
|
|
||||||
if (const auto init_ret = AudioOut::sceAudioOutInit();
|
|
||||||
init_ret < 0 && init_ret != ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT) {
|
|
||||||
return init_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioOut::OrbisAudioOutParamExtendedInformation ext_info{};
|
|
||||||
ext_info.data_format.Assign(AUDIO3D_OUTPUT_FORMAT);
|
|
||||||
state->audio_out_handle =
|
|
||||||
AudioOut::sceAudioOutOpen(0xFF, AudioOut::OrbisAudioOutPort::Audio3d, 0,
|
|
||||||
AUDIO3D_OUTPUT_BUFFER_FRAMES, AUDIO3D_SAMPLE_RATE, ext_info);
|
|
||||||
if (state->audio_out_handle < 0) {
|
|
||||||
return state->audio_out_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(const OrbisAudio3dPortId port_id,
|
|
||||||
OrbisAudio3dObjectId* object_id) {
|
|
||||||
LOG_INFO(Lib_Audio3d, "called, port_id = {}, object_id = {}", port_id,
|
|
||||||
static_cast<void*>(object_id));
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!object_id) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!object_id");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int last_id = 0;
|
|
||||||
*object_id = ++last_id;
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(const OrbisAudio3dPortId port_id,
|
|
||||||
OrbisAudio3dObjectId object_id,
|
|
||||||
const u64 num_attributes,
|
|
||||||
const OrbisAudio3dAttribute* attribute_array) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d,
|
|
||||||
"called, port_id = {}, object_id = {}, num_attributes = {}, attribute_array = {}",
|
|
||||||
port_id, object_id, num_attributes, fmt::ptr(attribute_array));
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& port = state->ports[port_id];
|
|
||||||
|
|
||||||
for (u64 i = 0; i < num_attributes; i++) {
|
|
||||||
const auto& attribute = attribute_array[i];
|
|
||||||
|
|
||||||
switch (attribute.attribute_id) {
|
|
||||||
case OrbisAudio3dAttributeId::ORBIS_AUDIO3D_ATTRIBUTE_PCM: {
|
|
||||||
const auto pcm = static_cast<OrbisAudio3dPcm*>(attribute.value);
|
|
||||||
// Object audio has 1 channel.
|
|
||||||
if (const auto ret = PortQueueAudio(port, *pcm, 1); ret != ORBIS_OK) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
LOG_ERROR(Lib_Audio3d, "Unsupported attribute ID: {:#x}",
|
|
||||||
static_cast<u32>(attribute.attribute_id));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(const OrbisAudio3dPortId port_id) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}", port_id);
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->ports[port_id].parameters.buffer_mode ==
|
|
||||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_NO_ADVANCE) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "port doesn't have advance capability");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& port = state->ports[port_id];
|
|
||||||
if (port.current_buffer.has_value()) {
|
|
||||||
// Free existing buffer before replacing.
|
|
||||||
SDL_free(port.current_buffer->sample_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!port.queue.empty()) {
|
|
||||||
port.current_buffer = port.queue.front();
|
|
||||||
port.queue.pop_front();
|
|
||||||
} else {
|
|
||||||
// Nothing to advance to.
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "Port advance with no buffer queued");
|
|
||||||
port.current_buffer = std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortClose() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(const OrbisAudio3dPortId port_id, u32* queue_level,
|
|
||||||
u32* queue_available) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, queue_level = {}, queue_available = {}", port_id,
|
|
||||||
static_cast<void*>(queue_level), static_cast<void*>(queue_available));
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!queue_level && !queue_available) {
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto port = state->ports[port_id];
|
|
||||||
const size_t size = port.queue.size();
|
|
||||||
|
|
||||||
if (queue_level) {
|
|
||||||
*queue_level = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue_available) {
|
|
||||||
*queue_available = port.parameters.queue_depth - size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(const OrbisUserServiceUserId user_id,
|
|
||||||
const OrbisAudio3dOpenParameters* parameters,
|
|
||||||
OrbisAudio3dPortId* port_id) {
|
|
||||||
LOG_INFO(Lib_Audio3d, "called, user_id = {}, parameters = {}, id = {}", user_id,
|
|
||||||
static_cast<const void*>(parameters), static_cast<void*>(port_id));
|
|
||||||
|
|
||||||
if (!state) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!initialized");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!parameters || !port_id) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!parameters || !id");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int id = static_cast<int>(state->ports.size()) + 1;
|
|
||||||
|
|
||||||
if (id > 3) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "id > 3");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
*port_id = id;
|
|
||||||
std::memcpy(&state->ports[id].parameters, parameters, sizeof(OrbisAudio3dOpenParameters));
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(const OrbisAudio3dPortId port_id,
|
|
||||||
const OrbisAudio3dBlocking blocking) {
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, blocking = {}", port_id,
|
|
||||||
magic_enum::enum_name(blocking));
|
|
||||||
|
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& port = state->ports[port_id];
|
|
||||||
if (port.parameters.buffer_mode !=
|
|
||||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "port doesn't have push capability");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!port.current_buffer.has_value()) {
|
|
||||||
// Nothing to push.
|
|
||||||
LOG_DEBUG(Lib_Audio3d, "Port push with no buffer ready");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Implement asynchronous blocking mode.
|
|
||||||
const auto& [sample_buffer, num_samples] = port.current_buffer.value();
|
|
||||||
return AudioOut::sceAudioOutOutput(state->audio_out_handle, sample_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(const OrbisAudio3dPortId port_id,
|
|
||||||
const OrbisAudio3dAttributeId attribute_id,
|
|
||||||
void* attribute, const u64 attribute_size) {
|
|
||||||
LOG_INFO(Lib_Audio3d,
|
LOG_INFO(Lib_Audio3d,
|
||||||
"called, port_id = {}, attribute_id = {}, attribute = {}, attribute_size = {}",
|
"uiPortId = {}, userId = {}, type = {}, index = {}, len = {}, freq = {}, param = {}",
|
||||||
port_id, static_cast<u32>(attribute_id), attribute, attribute_size);
|
uiPortId, userId, type, index, len, freq, param);
|
||||||
|
return ORBIS_OK;
|
||||||
if (!state->ports.contains(port_id)) {
|
|
||||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attribute) {
|
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle) {
|
||||||
LOG_ERROR(Lib_Audio3d, "!attribute");
|
LOG_INFO(Lib_Audio3d, "handle = {}", handle);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, const void* ptr) {
|
||||||
|
LOG_TRACE(Lib_Audio3d, "handle = {}", handle);
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "invalid Output ptr");
|
||||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(::Libraries::AudioOut::OrbisAudioOutOutputParam* param,
|
||||||
|
s32 num) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "num = {}", num);
|
||||||
|
if (param == nullptr) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "invalid OutputParam ptr");
|
||||||
|
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortCreate(u32 uiGranularity, OrbisAudio3dRate eRate, s64 iReserved,
|
||||||
|
OrbisAudio3dPortId* pId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiGranularity = {}, iReserved = {}", uiGranularity, iReserved);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortDestroy(OrbisAudio3dPortId uiPortId) {
|
||||||
|
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio3dPrivate
|
||||||
|
|
||||||
|
const char* PS4_SYSV_ABI sceAudio3dStrError(int iErrorCode) {
|
||||||
|
LOG_ERROR(Lib_Audio3d, "(PRIVATE) called, iErrorCode = {}", iErrorCode);
|
||||||
|
return "NOT_IMPLEMENTED";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio3dDebug
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
||||||
|
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortQueryDebug called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetList() {
|
||||||
|
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetList called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
||||||
|
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetParameters called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetState() {
|
||||||
|
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetState called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
||||||
|
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortFreeState called");
|
||||||
|
return ORBIS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unknown
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI sceAudio3dPortGetBufferLevel() {
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
int PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
int PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dStrError() {
|
int PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dTerminate() {
|
int PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
||||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
|
||||||
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
|
||||||
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dAudioOutOutput);
|
|
||||||
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dAudioOutOutputs);
|
|
||||||
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
|
||||||
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
|
||||||
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dCreateSpeakerArray);
|
|
||||||
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dDeleteSpeakerArray);
|
|
||||||
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dGetDefaultOpenParameters);
|
|
||||||
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dGetSpeakerArrayMemorySize);
|
|
||||||
LIB_FUNCTION("-R1DukFq7Dk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("-R1DukFq7Dk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dGetSpeakerArrayMixCoefficients);
|
sceAudio3dGetSpeakerArrayMixCoefficients);
|
||||||
LIB_FUNCTION("-Re+pCWvwjQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("-Re+pCWvwjQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dGetSpeakerArrayMixCoefficients2);
|
sceAudio3dGetSpeakerArrayMixCoefficients2);
|
||||||
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
|
||||||
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
|
||||||
LIB_FUNCTION("4uyHN9q4ZeU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dObjectSetAttributes);
|
|
||||||
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dObjectUnreserve);
|
|
||||||
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
|
||||||
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
|
||||||
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
|
||||||
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
|
||||||
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
|
||||||
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
|
||||||
LIB_FUNCTION("9ZA23Ia46Po", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dPortGetAttributesSupported);
|
|
||||||
LIB_FUNCTION("SEggctIeTcI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetList);
|
|
||||||
LIB_FUNCTION("flPcUaXVXcw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dPortGetParameters);
|
|
||||||
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
|
||||||
sceAudio3dPortGetQueueLevel);
|
|
||||||
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
|
||||||
LIB_FUNCTION("iRX6GJs9tvE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetStatus);
|
|
||||||
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
|
||||||
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
|
||||||
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dPortQueryDebug);
|
sceAudio3dPortQueryDebug);
|
||||||
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dPortSetAttribute);
|
sceAudio3dObjectUnreserve);
|
||||||
|
LIB_FUNCTION("4uyHN9q4ZeU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dObjectSetAttributes);
|
||||||
|
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dAudioOutOutput);
|
||||||
|
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dDeleteSpeakerArray);
|
||||||
|
LIB_FUNCTION("9ZA23Ia46Po", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dPortGetAttributesSupported);
|
||||||
|
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
||||||
|
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
||||||
|
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
||||||
|
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dAudioOutOutputs);
|
||||||
|
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dGetDefaultOpenParameters);
|
||||||
|
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
||||||
|
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
||||||
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dReportRegisterHandler);
|
sceAudio3dReportRegisterHandler);
|
||||||
|
LIB_FUNCTION("QqgTQQdzEMY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dPortGetBufferLevel);
|
||||||
|
LIB_FUNCTION("SEggctIeTcI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetList);
|
||||||
|
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
||||||
|
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
||||||
|
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
||||||
|
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
||||||
|
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
||||||
|
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dPortGetQueueLevel);
|
||||||
|
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dPortSetAttribute);
|
||||||
|
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
||||||
|
LIB_FUNCTION("flPcUaXVXcw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dPortGetParameters);
|
||||||
|
LIB_FUNCTION("iRX6GJs9tvE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetStatus);
|
||||||
|
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
||||||
|
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dGetSpeakerArrayMemorySize);
|
||||||
|
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
|
sceAudio3dCreateSpeakerArray);
|
||||||
|
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
||||||
|
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
||||||
LIB_FUNCTION("psv2gbihC1A", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("psv2gbihC1A", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dReportUnregisterHandler);
|
sceAudio3dReportUnregisterHandler);
|
||||||
|
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
||||||
|
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
||||||
|
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
||||||
LIB_FUNCTION("yEYXcbAGK14", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
LIB_FUNCTION("yEYXcbAGK14", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||||
sceAudio3dSetGpuRenderer);
|
sceAudio3dSetGpuRenderer);
|
||||||
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
|
||||||
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Libraries::Audio3d
|
} // namespace Libraries::Audio3d
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2025 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
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#include "common/types.h"
|
#include "common/types.h"
|
||||||
#include "core/libraries/audio/audioout.h"
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
namespace Core::Loader {
|
namespace Core::Loader {
|
||||||
class SymbolsResolver;
|
class SymbolsResolver;
|
||||||
|
@ -15,131 +13,123 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::Audio3d {
|
namespace Libraries::Audio3d {
|
||||||
|
|
||||||
|
class Audio3d;
|
||||||
|
|
||||||
using OrbisUserServiceUserId = s32;
|
using OrbisUserServiceUserId = s32;
|
||||||
|
using OrbisAudio3dPortId = u32;
|
||||||
|
using OrbisAudio3dObjectId = u32;
|
||||||
|
using OrbisAudio3dAttributeId = u32;
|
||||||
|
|
||||||
enum class OrbisAudio3dRate : u32 {
|
enum class OrbisAudio3dFormat {
|
||||||
ORBIS_AUDIO3D_RATE_48000 = 0,
|
S16 = 0,
|
||||||
|
Float = 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisAudio3dBufferMode : u32 {
|
enum class OrbisAudio3dRate {
|
||||||
ORBIS_AUDIO3D_BUFFER_NO_ADVANCE = 0,
|
Rate48000 = 0,
|
||||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_NO_PUSH = 1,
|
|
||||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH = 2,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class OrbisAudio3dBufferMode { NoAdvance = 0, AdvanceNoPush = 1, AdvanceAndPush = 2 };
|
||||||
|
|
||||||
|
enum class OrbisAudio3dBlocking {
|
||||||
|
Async = 0,
|
||||||
|
Sync = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisAudio3dPassthrough {
|
||||||
|
None = 0,
|
||||||
|
Left = 1,
|
||||||
|
Right = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisAudio3dOutputRoute {
|
||||||
|
Both = 0,
|
||||||
|
HmuOnly = 1,
|
||||||
|
TvOnly = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class OrbisAudio3dAmbisonics : u32 {
|
||||||
|
None = ~0U,
|
||||||
|
W = 0,
|
||||||
|
X = 1,
|
||||||
|
Y = 2,
|
||||||
|
Z = 3,
|
||||||
|
R = 4,
|
||||||
|
S = 5,
|
||||||
|
T = 6,
|
||||||
|
U = 7,
|
||||||
|
V = 8,
|
||||||
|
K = 9,
|
||||||
|
L = 10,
|
||||||
|
M = 11,
|
||||||
|
N = 12,
|
||||||
|
O = 13,
|
||||||
|
P = 14,
|
||||||
|
Q = 15
|
||||||
|
};
|
||||||
|
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePcm = 0x00000001;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePriority = 0x00000002;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePosition = 0x00000003;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeSpread = 0x00000004;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeGain = 0x00000005;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePassthrough = 0x00000006;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeResetState = 0x00000007;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeApplicationSpecific = 0x00000008;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeAmbisonics = 0x00000009;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeRestricted = 0x0000000A;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeOutputRoute = 0x0000000B;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeLateReverbLevel = 0x00010001;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadRadius = 0x00010002;
|
||||||
|
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadHeightAware = 0x00010003;
|
||||||
|
|
||||||
|
struct OrbisAudio3dSpeakerArray;
|
||||||
|
using OrbisAudio3dSpeakerArrayHandle = OrbisAudio3dSpeakerArray*; // head
|
||||||
|
|
||||||
struct OrbisAudio3dOpenParameters {
|
struct OrbisAudio3dOpenParameters {
|
||||||
u64 size_this;
|
size_t size_this;
|
||||||
u32 granularity;
|
u32 granularity;
|
||||||
OrbisAudio3dRate rate;
|
OrbisAudio3dRate rate;
|
||||||
u32 max_objects;
|
u32 max_objects;
|
||||||
u32 queue_depth;
|
u32 queue_depth;
|
||||||
OrbisAudio3dBufferMode buffer_mode;
|
OrbisAudio3dBufferMode buffer_mode;
|
||||||
int : 32;
|
char padding[32];
|
||||||
u32 num_beds;
|
u32 num_beds;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisAudio3dFormat : u32 {
|
struct OrbisAudio3dAttribute {
|
||||||
ORBIS_AUDIO3D_FORMAT_S16 = 0,
|
OrbisAudio3dAttributeId attribute_id;
|
||||||
ORBIS_AUDIO3D_FORMAT_FLOAT = 1,
|
char padding[32];
|
||||||
|
const void* p_value;
|
||||||
|
size_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisAudio3dOutputRoute : u32 {
|
struct OrbisAudio3dPosition {
|
||||||
ORBIS_AUDIO3D_OUTPUT_BOTH = 0,
|
float fX;
|
||||||
ORBIS_AUDIO3D_OUTPUT_HMU_ONLY = 1,
|
float fY;
|
||||||
ORBIS_AUDIO3D_OUTPUT_TV_ONLY = 2,
|
float fZ;
|
||||||
};
|
|
||||||
|
|
||||||
enum class OrbisAudio3dBlocking : u32 {
|
|
||||||
ORBIS_AUDIO3D_BLOCKING_ASYNC = 0,
|
|
||||||
ORBIS_AUDIO3D_BLOCKING_SYNC = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisAudio3dPcm {
|
struct OrbisAudio3dPcm {
|
||||||
OrbisAudio3dFormat format;
|
OrbisAudio3dFormat format;
|
||||||
void* sample_buffer;
|
const void* sample_buffer;
|
||||||
u32 num_samples;
|
u32 num_samples;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class OrbisAudio3dAttributeId : u32 {
|
struct OrbisAudio3dSpeakerArrayParameters {
|
||||||
ORBIS_AUDIO3D_ATTRIBUTE_PCM = 1,
|
OrbisAudio3dPosition* speaker_position;
|
||||||
|
u32 num_speakers;
|
||||||
|
bool is_3d;
|
||||||
|
void* buffer;
|
||||||
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
using OrbisAudio3dPortId = u32;
|
struct OrbisAudio3dApplicationSpecific {
|
||||||
using OrbisAudio3dObjectId = u32;
|
size_t size_this;
|
||||||
|
u8 application_specific[32];
|
||||||
struct OrbisAudio3dAttribute {
|
|
||||||
OrbisAudio3dAttributeId attribute_id;
|
|
||||||
int : 32;
|
|
||||||
void* value;
|
|
||||||
u64 value_size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AudioData {
|
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* sParameters);
|
||||||
u8* sample_buffer;
|
|
||||||
u32 num_samples;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Port {
|
|
||||||
OrbisAudio3dOpenParameters parameters{};
|
|
||||||
std::deque<AudioData> queue; // Only stores PCM buffers for now
|
|
||||||
std::optional<AudioData> current_buffer{};
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Audio3dState {
|
|
||||||
std::unordered_map<OrbisAudio3dPortId, Port> ports;
|
|
||||||
s32 audio_out_handle;
|
|
||||||
};
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId port_id, OrbisUserServiceUserId user_id,
|
|
||||||
s32 type, s32 index, u32 len, u32 freq,
|
|
||||||
AudioOut::OrbisAudioOutParamExtendedInformation param);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, void* ptr);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param, u32 num);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId port_id, u32 num_channels,
|
|
||||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId port_id, u32 num_channels,
|
|
||||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples,
|
|
||||||
OrbisAudio3dOutputRoute output_route, bool restricted);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(s64 reserved);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId port_id,
|
|
||||||
OrbisAudio3dObjectId* object_id);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId port_id,
|
|
||||||
OrbisAudio3dObjectId object_id, u64 num_attributes,
|
|
||||||
const OrbisAudio3dAttribute* attribute_array);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId port_id);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortClose();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId port_id, u32* queue_level,
|
|
||||||
u32* queue_available);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId user_id,
|
|
||||||
const OrbisAudio3dOpenParameters* parameters,
|
|
||||||
OrbisAudio3dPortId* port_id);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId port_id, OrbisAudio3dBlocking blocking);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId port_id,
|
|
||||||
OrbisAudio3dAttributeId attribute_id, void* attribute,
|
|
||||||
u64 attribute_size);
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dStrError();
|
|
||||||
s32 PS4_SYSV_ABI sceAudio3dTerminate();
|
|
||||||
|
|
||||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym);
|
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym);
|
||||||
} // namespace Libraries::Audio3d
|
} // namespace Libraries::Audio3d
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/libraries/error_codes.h"
|
||||||
|
|
||||||
constexpr int ORBIS_AUDIO3D_ERROR_UNKNOWN = 0x80EA0001;
|
constexpr int ORBIS_AUDIO3D_ERROR_UNKNOWN = 0x80EA0001;
|
||||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_PORT = 0x80EA0002;
|
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_PORT = 0x80EA0002;
|
||||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_OBJECT = 0x80EA0003;
|
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_OBJECT = 0x80EA0003;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
// 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 "ngs2_error.h"
|
#include "audio3d_error.h"
|
||||||
#include "ngs2_impl.h"
|
#include "audio3d_impl.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/kernel/kernel.h"
|
||||||
|
|
||||||
using namespace Libraries::Kernel;
|
using namespace Libraries::Kernel;
|
||||||
|
|
||||||
namespace Libraries::Ngs2 {} // namespace Libraries::Ngs2
|
namespace Libraries::Audio3d {} // namespace Libraries::Audio3d
|
16
src/core/libraries/audio3d/audio3d_impl.h
Normal file
16
src/core/libraries/audio3d/audio3d_impl.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "audio3d.h"
|
||||||
|
|
||||||
|
namespace Libraries::Audio3d {
|
||||||
|
|
||||||
|
class Audio3d {
|
||||||
|
public:
|
||||||
|
private:
|
||||||
|
using OrbisAudio3dPluginId = u32;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Libraries::Audio3d
|
|
@ -9,29 +9,29 @@
|
||||||
|
|
||||||
namespace Libraries::DiscMap {
|
namespace Libraries::DiscMap {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize(s64 fflags, int* ret1, int* ret2) {
|
int PS4_SYSV_ABI sceDiscMapGetPackageSize() {
|
||||||
|
LOG_WARNING(Lib_DiscMap, "(DUMMY) called");
|
||||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD(char* path, s64 offset, s64 nbytes, int* ret) {
|
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD() {
|
||||||
|
LOG_WARNING(Lib_DiscMap, "(DUMMY) called");
|
||||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A() {
|
||||||
int* ret2) {
|
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||||
*flags = 0;
|
|
||||||
*ret1 = 0;
|
|
||||||
*ret2 = 0;
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9() {
|
||||||
int* ret2) {
|
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8() {
|
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8() {
|
||||||
return ORBIS_DISC_MAP_ERROR_NO_BITMAP_INFO;
|
LOG_ERROR(Lib_DiscMap, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym) {
|
||||||
|
|
|
@ -10,12 +10,10 @@ class SymbolsResolver;
|
||||||
}
|
}
|
||||||
namespace Libraries::DiscMap {
|
namespace Libraries::DiscMap {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceDiscMapGetPackageSize(s64 fflags, int* ret1, int* ret2);
|
int PS4_SYSV_ABI sceDiscMapGetPackageSize();
|
||||||
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD(char* path, s64 offset, s64 nbytes, int* ret);
|
int PS4_SYSV_ABI sceDiscMapIsRequestOnHDD();
|
||||||
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
int PS4_SYSV_ABI Func_7C980FFB0AA27E7A();
|
||||||
int* ret2);
|
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9();
|
||||||
int PS4_SYSV_ABI Func_8A828CAEE7EDD5E9(char* path, s64 offset, s64 nbytes, int* flags, int* ret1,
|
|
||||||
int* ret2);
|
|
||||||
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8();
|
int PS4_SYSV_ABI Func_E7EBCE96E92F91F8();
|
||||||
|
|
||||||
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym);
|
void RegisterlibSceDiscMap(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
|
@ -2804,7 +2804,7 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
|
||||||
liverpool = std::make_unique<AmdGpu::Liverpool>();
|
liverpool = std::make_unique<AmdGpu::Liverpool>();
|
||||||
presenter = std::make_unique<Vulkan::Presenter>(*g_window, liverpool.get());
|
presenter = std::make_unique<Vulkan::Presenter>(*g_window, liverpool.get());
|
||||||
|
|
||||||
const s32 result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
||||||
if (result != ORBIS_OK) {
|
if (result != ORBIS_OK) {
|
||||||
sdk_version = 0;
|
sdk_version = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,35 +83,9 @@ int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error PS4_SYSV_ABI sceImeDialogGetPanelSize(const OrbisImeDialogParam* param, u32* width,
|
int PS4_SYSV_ABI sceImeDialogGetPanelSize() {
|
||||||
u32* height) {
|
LOG_ERROR(Lib_ImeDialog, "(STUBBED) called");
|
||||||
LOG_INFO(Lib_ImeDialog, "called");
|
return ORBIS_OK;
|
||||||
|
|
||||||
if (!width || !height) {
|
|
||||||
return Error::INVALID_ADDRESS;
|
|
||||||
}
|
|
||||||
switch (param->type) {
|
|
||||||
case OrbisImeType::Default:
|
|
||||||
case OrbisImeType::BasicLatin:
|
|
||||||
case OrbisImeType::Url:
|
|
||||||
case OrbisImeType::Mail:
|
|
||||||
*width = 500; // original: 793
|
|
||||||
if (True(param->option & OrbisImeDialogOption::Multiline)) {
|
|
||||||
*height = 300; // original: 576
|
|
||||||
} else {
|
|
||||||
*height = 150; // original: 476
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case OrbisImeType::Number:
|
|
||||||
*width = 370;
|
|
||||||
*height = 470;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_ERROR(Lib_ImeDialog, "Unknown OrbisImeType: {}", (u32)param->type);
|
|
||||||
return Error::INVALID_PARAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Error::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() {
|
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() {
|
||||||
|
|
|
@ -13,7 +13,7 @@ class SymbolsResolver;
|
||||||
|
|
||||||
namespace Libraries::ImeDialog {
|
namespace Libraries::ImeDialog {
|
||||||
|
|
||||||
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 2048;
|
constexpr u32 ORBIS_IME_DIALOG_MAX_TEXT_LENGTH = 0x78;
|
||||||
|
|
||||||
enum class Error : u32 {
|
enum class Error : u32 {
|
||||||
OK = 0x0,
|
OK = 0x0,
|
||||||
|
@ -155,8 +155,7 @@ Error PS4_SYSV_ABI sceImeDialogForceClose();
|
||||||
Error PS4_SYSV_ABI sceImeDialogForTestFunction();
|
Error PS4_SYSV_ABI sceImeDialogForTestFunction();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState();
|
int PS4_SYSV_ABI sceImeDialogGetCurrentStarState();
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm();
|
int PS4_SYSV_ABI sceImeDialogGetPanelPositionAndForm();
|
||||||
Error PS4_SYSV_ABI sceImeDialogGetPanelSize(const OrbisImeDialogParam* param, u32* width,
|
int PS4_SYSV_ABI sceImeDialogGetPanelSize();
|
||||||
u32* height);
|
|
||||||
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended();
|
int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended();
|
||||||
Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result);
|
Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result);
|
||||||
OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus();
|
OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus();
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/libraries/kernel/file_system.h"
|
|
||||||
#include "core/libraries/kernel/orbis_error.h"
|
|
||||||
#include "core/libraries/libs.h"
|
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
|
||||||
|
|
||||||
void PS4_SYSV_ABI sceKernelDebugOutText(void* unk, char* text) {
|
|
||||||
sceKernelWrite(1, text, strlen(text));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterDebug(Core::Loader::SymbolsResolver* sym) {
|
|
||||||
LIB_FUNCTION("9JYNqN6jAKI", "libkernel", 1, "libkernel", 1, 1, sceKernelDebugOutText);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
|
|
@ -1,14 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Core::Loader {
|
|
||||||
class SymbolsResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Libraries::Kernel {
|
|
||||||
|
|
||||||
void RegisterDebug(Core::Loader::SymbolsResolver* sym);
|
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
|
|
@ -61,18 +61,6 @@ struct SceKernelEvent {
|
||||||
void* udata = nullptr; /* opaque user data identifier */
|
void* udata = nullptr; /* opaque user data identifier */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrbisVideoOutEventHint {
|
|
||||||
u64 event_id : 8;
|
|
||||||
u64 video_id : 8;
|
|
||||||
u64 flip_arg : 48;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrbisVideoOutEventData {
|
|
||||||
u64 time : 12;
|
|
||||||
u64 count : 4;
|
|
||||||
u64 flip_arg : 48;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct EqueueEvent {
|
struct EqueueEvent {
|
||||||
SceKernelEvent event;
|
SceKernelEvent event;
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
|
@ -96,18 +84,19 @@ struct EqueueEvent {
|
||||||
|
|
||||||
void TriggerDisplay(void* data) {
|
void TriggerDisplay(void* data) {
|
||||||
is_triggered = true;
|
is_triggered = true;
|
||||||
if (data != nullptr) {
|
auto hint = reinterpret_cast<u64>(data);
|
||||||
auto event_data = static_cast<OrbisVideoOutEventData>(event.data);
|
if (hint != 0) {
|
||||||
auto event_hint_raw = reinterpret_cast<u64>(data);
|
auto hint_h = static_cast<u32>(hint >> 8) & 0xFFFFFF;
|
||||||
auto event_hint = static_cast<OrbisVideoOutEventHint>(event_hint_raw);
|
auto ident_h = static_cast<u32>(event.ident >> 40);
|
||||||
if (event_hint.event_id == event.ident && event.ident != 0xfe) {
|
if ((static_cast<u32>(hint) & 0xFF) == event.ident && event.ident != 0xFE &&
|
||||||
|
((hint_h ^ ident_h) & 0xFF) == 0) {
|
||||||
auto time = Common::FencedRDTSC();
|
auto time = Common::FencedRDTSC();
|
||||||
auto counter = event_data.count;
|
auto mask = 0xF000;
|
||||||
if (counter != 0xf) {
|
if ((static_cast<u32>(event.data) & 0xF000) != 0xF000) {
|
||||||
counter++;
|
mask = (static_cast<u32>(event.data) + 0x1000) & 0xF000;
|
||||||
}
|
}
|
||||||
event.data =
|
event.data = (mask | static_cast<u64>(static_cast<u32>(time) & 0xFFF) |
|
||||||
(time & 0xfff) | (counter << 0xc) | (event_hint_raw & 0xffffffffffff0000);
|
(hint & 0xFFFFFFFFFFFF0000));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -65,10 +65,10 @@ constexpr int ORBIS_KERNEL_O_DSYNC = 0x1000;
|
||||||
constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000;
|
constexpr int ORBIS_KERNEL_O_DIRECT = 0x00010000;
|
||||||
constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000;
|
constexpr int ORBIS_KERNEL_O_DIRECTORY = 0x00020000;
|
||||||
|
|
||||||
s64 PS4_SYSV_ABI sceKernelWrite(s32 fd, const void* buf, size_t nbytes);
|
s64 PS4_SYSV_ABI sceKernelWrite(int d, const void* buf, size_t nbytes);
|
||||||
s64 PS4_SYSV_ABI sceKernelRead(s32 fd, void* buf, size_t nbytes);
|
s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes);
|
||||||
s64 PS4_SYSV_ABI sceKernelPread(s32 fd, void* buf, size_t nbytes, s64 offset);
|
s64 PS4_SYSV_ABI sceKernelPread(int d, void* buf, size_t nbytes, s64 offset);
|
||||||
s64 PS4_SYSV_ABI sceKernelPwrite(s32 fd, void* buf, size_t nbytes, s64 offset);
|
s64 PS4_SYSV_ABI sceKernelPwrite(int d, void* buf, size_t nbytes, s64 offset);
|
||||||
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym);
|
void RegisterFileSystem(Core::Loader::SymbolsResolver* sym);
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include "common/va_ctx.h"
|
#include "common/va_ctx.h"
|
||||||
#include "core/file_sys/fs.h"
|
#include "core/file_sys/fs.h"
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/kernel/debug.h"
|
|
||||||
#include "core/libraries/kernel/equeue.h"
|
#include "core/libraries/kernel/equeue.h"
|
||||||
#include "core/libraries/kernel/file_system.h"
|
#include "core/libraries/kernel/file_system.h"
|
||||||
#include "core/libraries/kernel/kernel.h"
|
#include "core/libraries/kernel/kernel.h"
|
||||||
|
@ -24,7 +23,6 @@
|
||||||
#include "core/libraries/kernel/threads/exception.h"
|
#include "core/libraries/kernel/threads/exception.h"
|
||||||
#include "core/libraries/kernel/time.h"
|
#include "core/libraries/kernel/time.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/network/sys_net.h"
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
#include <Rpc.h>
|
#include <Rpc.h>
|
||||||
|
@ -87,23 +85,17 @@ int ErrnoToSceKernelError(int error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPosixErrno(int e) {
|
void SetPosixErrno(int e) {
|
||||||
// Some error numbers are different between supported OSes
|
// Some error numbers are different between supported OSes or the PS4
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case EPERM:
|
case EPERM:
|
||||||
g_posix_errno = POSIX_EPERM;
|
g_posix_errno = POSIX_EPERM;
|
||||||
break;
|
break;
|
||||||
case ENOENT:
|
case EAGAIN:
|
||||||
g_posix_errno = POSIX_ENOENT;
|
g_posix_errno = POSIX_EAGAIN;
|
||||||
break;
|
|
||||||
case EDEADLK:
|
|
||||||
g_posix_errno = POSIX_EDEADLK;
|
|
||||||
break;
|
break;
|
||||||
case ENOMEM:
|
case ENOMEM:
|
||||||
g_posix_errno = POSIX_ENOMEM;
|
g_posix_errno = POSIX_ENOMEM;
|
||||||
break;
|
break;
|
||||||
case EACCES:
|
|
||||||
g_posix_errno = POSIX_EACCES;
|
|
||||||
break;
|
|
||||||
case EINVAL:
|
case EINVAL:
|
||||||
g_posix_errno = POSIX_EINVAL;
|
g_posix_errno = POSIX_EINVAL;
|
||||||
break;
|
break;
|
||||||
|
@ -113,14 +105,13 @@ void SetPosixErrno(int e) {
|
||||||
case ERANGE:
|
case ERANGE:
|
||||||
g_posix_errno = POSIX_ERANGE;
|
g_posix_errno = POSIX_ERANGE;
|
||||||
break;
|
break;
|
||||||
case EAGAIN:
|
case EDEADLK:
|
||||||
g_posix_errno = POSIX_EAGAIN;
|
g_posix_errno = POSIX_EDEADLK;
|
||||||
break;
|
break;
|
||||||
case ETIMEDOUT:
|
case ETIMEDOUT:
|
||||||
g_posix_errno = POSIX_ETIMEDOUT;
|
g_posix_errno = POSIX_ETIMEDOUT;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_WARNING(Kernel, "Unhandled errno {}", e);
|
|
||||||
g_posix_errno = e;
|
g_posix_errno = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,6 +133,14 @@ void PS4_SYSV_ABI sceLibcHeapGetTraceInfo(HeapInfoInfo* info) {
|
||||||
info->getSegmentInfo = 0;
|
info->getSegmentInfo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s64 PS4_SYSV_ABI ps4__write(int d, const char* buf, std::size_t nbytes) {
|
||||||
|
return sceKernelWrite(d, buf, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {
|
||||||
|
return sceKernelRead(d, buf, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
struct OrbisKernelUuid {
|
struct OrbisKernelUuid {
|
||||||
u32 timeLow;
|
u32 timeLow;
|
||||||
u16 timeMid;
|
u16 timeMid;
|
||||||
|
@ -197,6 +196,10 @@ const char* PS4_SYSV_ABI sceKernelGetFsSandboxRandomWord() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PS4_SYSV_ABI posix_connect() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI _sigprocmask() {
|
int PS4_SYSV_ABI _sigprocmask() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -217,38 +220,22 @@ void RegisterKernel(Core::Loader::SymbolsResolver* sym) {
|
||||||
Libraries::Kernel::RegisterProcess(sym);
|
Libraries::Kernel::RegisterProcess(sym);
|
||||||
Libraries::Kernel::RegisterException(sym);
|
Libraries::Kernel::RegisterException(sym);
|
||||||
Libraries::Kernel::RegisterAio(sym);
|
Libraries::Kernel::RegisterAio(sym);
|
||||||
Libraries::Kernel::RegisterDebug(sym);
|
|
||||||
|
|
||||||
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
LIB_OBJ("f7uOxY9mM1U", "libkernel", 1, "libkernel", 1, 1, &g_stack_chk_guard);
|
||||||
LIB_FUNCTION("PfccT7qURYE", "libkernel", 1, "libkernel", 1, 1, kernel_ioctl);
|
LIB_FUNCTION("PfccT7qURYE", "libkernel", 1, "libkernel", 1, 1, kernel_ioctl);
|
||||||
LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetFsSandboxRandomWord);
|
LIB_FUNCTION("JGfTMBOdUJo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetFsSandboxRandomWord);
|
||||||
|
LIB_FUNCTION("XVL8So3QJUk", "libkernel", 1, "libkernel", 1, 1, posix_connect);
|
||||||
LIB_FUNCTION("6xVpy0Fdq+I", "libkernel", 1, "libkernel", 1, 1, _sigprocmask);
|
LIB_FUNCTION("6xVpy0Fdq+I", "libkernel", 1, "libkernel", 1, 1, _sigprocmask);
|
||||||
LIB_FUNCTION("Xjoosiw+XPI", "libkernel", 1, "libkernel", 1, 1, sceKernelUuidCreate);
|
LIB_FUNCTION("Xjoosiw+XPI", "libkernel", 1, "libkernel", 1, 1, sceKernelUuidCreate);
|
||||||
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
LIB_FUNCTION("Ou3iL1abvng", "libkernel", 1, "libkernel", 1, 1, stack_chk_fail);
|
||||||
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
LIB_FUNCTION("9BcDykPmo1I", "libkernel", 1, "libkernel", 1, 1, __Error);
|
||||||
|
LIB_FUNCTION("DRuBt2pvICk", "libkernel", 1, "libkernel", 1, 1, ps4__read);
|
||||||
LIB_FUNCTION("k+AXqu2-eBc", "libkernel", 1, "libkernel", 1, 1, posix_getpagesize);
|
LIB_FUNCTION("k+AXqu2-eBc", "libkernel", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||||
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
|
LIB_FUNCTION("k+AXqu2-eBc", "libScePosix", 1, "libkernel", 1, 1, posix_getpagesize);
|
||||||
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
LIB_FUNCTION("NWtTN10cJzE", "libSceLibcInternalExt", 1, "libSceLibcInternal", 1, 1,
|
||||||
sceLibcHeapGetTraceInfo);
|
sceLibcHeapGetTraceInfo);
|
||||||
|
LIB_FUNCTION("FxVZqBAA7ks", "libkernel", 1, "libkernel", 1, 1, ps4__write);
|
||||||
// network
|
LIB_FUNCTION("FN4gaPmuFV8", "libScePosix", 1, "libkernel", 1, 1, ps4__write);
|
||||||
LIB_FUNCTION("XVL8So3QJUk", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_connect);
|
|
||||||
LIB_FUNCTION("TU-d9PfIHPM", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_socketex);
|
|
||||||
LIB_FUNCTION("KuOmgKoqCdY", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
|
|
||||||
LIB_FUNCTION("pxnCmagrtao", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_listen);
|
|
||||||
LIB_FUNCTION("3e+4Iv7IJ8U", "libkernel", 1, "libkernel", 1, 1, Libraries::Net::sys_accept);
|
|
||||||
LIB_FUNCTION("TU-d9PfIHPM", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_socket);
|
|
||||||
LIB_FUNCTION("oBr313PppNE", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_sendto);
|
|
||||||
LIB_FUNCTION("lUk6wrGXyMw", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_recvfrom);
|
|
||||||
LIB_FUNCTION("fFxGkxF2bVo", "libScePosix", 1, "libkernel", 1, 1,
|
|
||||||
Libraries::Net::sys_setsockopt);
|
|
||||||
LIB_FUNCTION("RenI1lL1WFk", "libScePosix", 1, "libkernel", 1, 1,
|
|
||||||
Libraries::Net::sys_getsockname);
|
|
||||||
LIB_FUNCTION("KuOmgKoqCdY", "libScePosix", 1, "libkernel", 1, 1, Libraries::Net::sys_bind);
|
|
||||||
LIB_FUNCTION("5jRCs2axtr4", "libScePosix", 1, "libkernel", 1, 1,
|
|
||||||
Libraries::Net::sceNetInetNtop); // TODO fix it to sys_ ...
|
|
||||||
LIB_FUNCTION("4n51s0zEf0c", "libScePosix", 1, "libkernel", 1, 1,
|
|
||||||
Libraries::Net::sceNetInetPton); // TODO fix it to sys_ ...
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -18,7 +18,6 @@ namespace Libraries::Kernel {
|
||||||
void ErrSceToPosix(int result);
|
void ErrSceToPosix(int result);
|
||||||
int ErrnoToSceKernelError(int e);
|
int ErrnoToSceKernelError(int e);
|
||||||
void SetPosixErrno(int e);
|
void SetPosixErrno(int e);
|
||||||
int* PS4_SYSV_ABI __Error();
|
|
||||||
|
|
||||||
template <StringLiteral name, class F, F f>
|
template <StringLiteral name, class F, F f>
|
||||||
struct WrapperImpl;
|
struct WrapperImpl;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
namespace Libraries::Kernel {
|
namespace Libraries::Kernel {
|
||||||
|
|
||||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
|
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
|
||||||
LOG_TRACE(Kernel_Vmm, "called");
|
LOG_WARNING(Kernel_Vmm, "called");
|
||||||
const auto* memory = Core::Memory::Instance();
|
const auto* memory = Core::Memory::Instance();
|
||||||
return memory->GetTotalDirectSize();
|
return memory->GetTotalDirectSize();
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,12 @@ s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchE
|
||||||
if (physAddrOut == nullptr || sizeOut == nullptr) {
|
if (physAddrOut == nullptr || sizeOut == nullptr) {
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
}
|
}
|
||||||
|
if (searchEnd > sceKernelGetDirectMemorySize()) {
|
||||||
|
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||||
|
}
|
||||||
|
if (searchEnd <= searchStart) {
|
||||||
|
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
auto* memory = Core::Memory::Instance();
|
auto* memory = Core::Memory::Instance();
|
||||||
|
|
||||||
|
|
|
@ -127,67 +127,6 @@ int PS4_SYSV_ABI sceKernelGetModuleInfoFromAddr(VAddr addr, int flags,
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelGetModuleInfo(s32 handle, Core::OrbisKernelModuleInfo* info) {
|
|
||||||
if (info == nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
|
||||||
}
|
|
||||||
if (info->st_size != sizeof(Core::OrbisKernelModuleInfo)) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
|
||||||
auto* module = linker->GetModule(handle);
|
|
||||||
if (module == nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
|
||||||
}
|
|
||||||
*info = module->GetModuleInfo();
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelGetModuleInfoInternal(s32 handle, Core::OrbisKernelModuleInfoEx* info) {
|
|
||||||
if (info == nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
|
||||||
}
|
|
||||||
if (info->st_size != sizeof(Core::OrbisKernelModuleInfoEx)) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
|
||||||
auto* module = linker->GetModule(handle);
|
|
||||||
if (module == nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_ESRCH;
|
|
||||||
}
|
|
||||||
*info = module->GetModuleInfoEx();
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelGetModuleList(s32* handles, u64 num_array, u64* out_count) {
|
|
||||||
if (handles == nullptr || out_count == nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_EFAULT;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* linker = Common::Singleton<Core::Linker>::Instance();
|
|
||||||
u64 count = 0;
|
|
||||||
auto* module = linker->GetModule(count);
|
|
||||||
while (module != nullptr && count < num_array) {
|
|
||||||
handles[count] = count;
|
|
||||||
count++;
|
|
||||||
module = linker->GetModule(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == num_array && module != nullptr) {
|
|
||||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out_count = count;
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI exit(s32 status) {
|
|
||||||
UNREACHABLE_MSG("Exiting with status code {}", status);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
|
void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
LIB_FUNCTION("WB66evu8bsU", "libkernel", 1, "libkernel", 1, 1, sceKernelGetCompiledSdkVersion);
|
||||||
LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, sceKernelIsNeoMode);
|
LIB_FUNCTION("WslcK1FQcGI", "libkernel", 1, "libkernel", 1, 1, sceKernelIsNeoMode);
|
||||||
|
@ -197,10 +136,6 @@ void RegisterProcess(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
|
LIB_FUNCTION("LwG8g3niqwA", "libkernel", 1, "libkernel", 1, 1, sceKernelDlsym);
|
||||||
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind);
|
LIB_FUNCTION("RpQJJVKTiFM", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoForUnwind);
|
||||||
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr);
|
LIB_FUNCTION("f7KBOafysXo", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoFromAddr);
|
||||||
LIB_FUNCTION("kUpgrXIrz7Q", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfo);
|
|
||||||
LIB_FUNCTION("HZO7xOos4xc", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleInfoInternal);
|
|
||||||
LIB_FUNCTION("IuxnUuXk6Bg", "libkernel", 1, "libkernel", 1, 1, sceKernelGetModuleList);
|
|
||||||
LIB_FUNCTION("6Z83sYWFlA8", "libkernel", 1, "libkernel", 1, 1, exit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries::Kernel
|
} // namespace Libraries::Kernel
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// 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 "core/libraries/kernel/orbis_error.h"
|
|
||||||
#include "core/libraries/kernel/threads/exception.h"
|
#include "core/libraries/kernel/threads/exception.h"
|
||||||
#include "core/libraries/kernel/threads/pthread.h"
|
#include "core/libraries/kernel/threads/pthread.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
|
@ -149,19 +148,13 @@ int PS4_SYSV_ABI sceKernelRaiseException(PthreadT thread, int signum) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseException(s32 error, s64 unk) {
|
int PS4_SYSV_ABI sceKernelDebugRaiseException() {
|
||||||
if (unk != 0) {
|
UNREACHABLE();
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
|
||||||
UNREACHABLE_MSG("error {:#x}", error);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode(s32 error, s64 unk) {
|
int PS4_SYSV_ABI sceKernelDebugRaiseExceptionOnReleaseMode() {
|
||||||
if (unk != 0) {
|
UNREACHABLE();
|
||||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
|
||||||
}
|
|
||||||
UNREACHABLE_MSG("error {:#x}", error);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +163,7 @@ void RegisterException(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("WkwEd3N7w0Y", "libkernel_unity", 1, "libkernel", 1, 1,
|
||||||
sceKernelInstallExceptionHandler);
|
sceKernelInstallExceptionHandler);
|
||||||
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel_unity", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("Qhv5ARAoOEc", "libkernel_unity", 1, "libkernel", 1, 1,
|
||||||
sceKernelRemoveExceptionHandler);
|
sceKernelRemoveExceptionHandler)
|
||||||
LIB_FUNCTION("OMDRKKAZ8I4", "libkernel", 1, "libkernel", 1, 1, sceKernelDebugRaiseException);
|
LIB_FUNCTION("OMDRKKAZ8I4", "libkernel", 1, "libkernel", 1, 1, sceKernelDebugRaiseException);
|
||||||
LIB_FUNCTION("zE-wXIZjLoM", "libkernel", 1, "libkernel", 1, 1,
|
LIB_FUNCTION("zE-wXIZjLoM", "libkernel", 1, "libkernel", 1, 1,
|
||||||
sceKernelDebugRaiseExceptionOnReleaseMode);
|
sceKernelDebugRaiseExceptionOnReleaseMode);
|
||||||
|
|
|
@ -147,11 +147,6 @@ void RegisterSpec(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("0-KXaS70xy4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getspecific);
|
LIB_FUNCTION("0-KXaS70xy4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getspecific);
|
||||||
LIB_FUNCTION("WrOLvHU0yQM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
LIB_FUNCTION("WrOLvHU0yQM", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
||||||
|
|
||||||
// Posix-Kernel
|
|
||||||
LIB_FUNCTION("mqULNdimTn0", "libkernel", 1, "libkernel", 1, 1, posix_pthread_key_create);
|
|
||||||
LIB_FUNCTION("0-KXaS70xy4", "libkernel", 1, "libkernel", 1, 1, posix_pthread_getspecific);
|
|
||||||
LIB_FUNCTION("WrOLvHU0yQM", "libkernel", 1, "libkernel", 1, 1, posix_pthread_setspecific);
|
|
||||||
|
|
||||||
// Orbis
|
// Orbis
|
||||||
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_create));
|
LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_create));
|
||||||
LIB_FUNCTION("PrdHuuDekhY", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_delete));
|
LIB_FUNCTION("PrdHuuDekhY", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_delete));
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "core/libraries/network/netctl.h"
|
#include "core/libraries/network/netctl.h"
|
||||||
#include "core/libraries/network/ssl.h"
|
#include "core/libraries/network/ssl.h"
|
||||||
#include "core/libraries/network/ssl2.h"
|
#include "core/libraries/network/ssl2.h"
|
||||||
#include "core/libraries/np_auth/np_auth.h"
|
|
||||||
#include "core/libraries/np_common/np_common.h"
|
#include "core/libraries/np_common/np_common.h"
|
||||||
#include "core/libraries/np_manager/np_manager.h"
|
#include "core/libraries/np_manager/np_manager.h"
|
||||||
#include "core/libraries/np_party/np_party.h"
|
#include "core/libraries/np_party/np_party.h"
|
||||||
|
@ -51,7 +50,6 @@
|
||||||
#include "core/libraries/system/sysmodule.h"
|
#include "core/libraries/system/sysmodule.h"
|
||||||
#include "core/libraries/system/systemservice.h"
|
#include "core/libraries/system/systemservice.h"
|
||||||
#include "core/libraries/system/userservice.h"
|
#include "core/libraries/system/userservice.h"
|
||||||
#include "core/libraries/ulobjmgr/ulobjmgr.h"
|
|
||||||
#include "core/libraries/usbd/usbd.h"
|
#include "core/libraries/usbd/usbd.h"
|
||||||
#include "core/libraries/videodec/videodec.h"
|
#include "core/libraries/videodec/videodec.h"
|
||||||
#include "core/libraries/videodec/videodec2.h"
|
#include "core/libraries/videodec/videodec2.h"
|
||||||
|
@ -89,7 +87,6 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
||||||
Libraries::NpScore::RegisterlibSceNpScore(sym);
|
Libraries::NpScore::RegisterlibSceNpScore(sym);
|
||||||
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
||||||
Libraries::NpWebApi::RegisterlibSceNpWebApi(sym);
|
Libraries::NpWebApi::RegisterlibSceNpWebApi(sym);
|
||||||
Libraries::NpAuth::RegisterlibSceNpAuth(sym);
|
|
||||||
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
||||||
Libraries::AppContent::RegisterlibSceAppContent(sym);
|
Libraries::AppContent::RegisterlibSceAppContent(sym);
|
||||||
Libraries::PngDec::RegisterlibScePngDec(sym);
|
Libraries::PngDec::RegisterlibScePngDec(sym);
|
||||||
|
@ -118,8 +115,6 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
||||||
Libraries::NpParty::RegisterlibSceNpParty(sym);
|
Libraries::NpParty::RegisterlibSceNpParty(sym);
|
||||||
Libraries::Zlib::RegisterlibSceZlib(sym);
|
Libraries::Zlib::RegisterlibSceZlib(sym);
|
||||||
Libraries::Hmd::RegisterlibSceHmd(sym);
|
Libraries::Hmd::RegisterlibSceHmd(sym);
|
||||||
Libraries::DiscMap::RegisterlibSceDiscMap(sym);
|
|
||||||
Libraries::Ulobjmgr::RegisterlibSceUlobjmgr(sym);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Libraries
|
} // namespace Libraries
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
namespace Libraries::Move {
|
namespace Libraries::Move {
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceMoveOpen() {
|
int PS4_SYSV_ABI sceMoveOpen() {
|
||||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
LOG_ERROR(Lib_Move, "(STUBBED) called");
|
||||||
return ORBIS_FAIL;
|
return ORBIS_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,6 @@ int PS4_SYSV_ABI sceMoveGetDeviceInfo() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceMoveReadStateLatest() {
|
|
||||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
|
||||||
return ORBIS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceMoveReadStateRecent() {
|
int PS4_SYSV_ABI sceMoveReadStateRecent() {
|
||||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -41,7 +36,6 @@ int PS4_SYSV_ABI sceMoveInit() {
|
||||||
void RegisterlibSceMove(Core::Loader::SymbolsResolver* sym) {
|
void RegisterlibSceMove(Core::Loader::SymbolsResolver* sym) {
|
||||||
LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", 1, 1, sceMoveOpen);
|
LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", 1, 1, sceMoveOpen);
|
||||||
LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveGetDeviceInfo);
|
LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveGetDeviceInfo);
|
||||||
LIB_FUNCTION("ttU+JOhShl4", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateLatest);
|
|
||||||
LIB_FUNCTION("f2bcpK6kJfg", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateRecent);
|
LIB_FUNCTION("f2bcpK6kJfg", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateRecent);
|
||||||
LIB_FUNCTION("tsZi60H4ypY", "libSceMove", 1, "libSceMove", 1, 1, sceMoveTerm);
|
LIB_FUNCTION("tsZi60H4ypY", "libSceMove", 1, "libSceMove", 1, 1, sceMoveTerm);
|
||||||
LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveInit);
|
LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveInit);
|
||||||
|
|
|
@ -10,24 +10,16 @@
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <core/libraries/kernel/kernel.h>
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/singleton.h"
|
|
||||||
#include "core/libraries/error_codes.h"
|
#include "core/libraries/error_codes.h"
|
||||||
#include "core/libraries/libs.h"
|
#include "core/libraries/libs.h"
|
||||||
#include "core/libraries/network/net.h"
|
#include "core/libraries/network/net.h"
|
||||||
#include "net_error.h"
|
|
||||||
#include "net_util.h"
|
|
||||||
#include "netctl.h"
|
|
||||||
#include "sys_net.h"
|
|
||||||
|
|
||||||
namespace Libraries::Net {
|
namespace Libraries::Net {
|
||||||
|
|
||||||
static thread_local int32_t net_errno = 0;
|
static thread_local int32_t net_errno = 0;
|
||||||
|
|
||||||
static bool g_isNetInitialized = true; // TODO init it properly
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI in6addr_any() {
|
int PS4_SYSV_ABI in6addr_any() {
|
||||||
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
|
@ -69,45 +61,8 @@ int PS4_SYSV_ABI sce_net_in6addr_nodelocal_allnodes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
OrbisNetId PS4_SYSV_ABI sceNetAccept(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_accept(s, addr, paddrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetAddrConfig6GetInfo() {
|
int PS4_SYSV_ABI sceNetAddrConfig6GetInfo() {
|
||||||
|
@ -166,45 +121,8 @@ int PS4_SYSV_ABI sceNetBandwidthControlSetPolicy() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PS4_SYSV_ABI sceNetBind(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_bind(s, addr, addrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetClearDnsCache() {
|
int PS4_SYSV_ABI sceNetClearDnsCache() {
|
||||||
|
@ -547,46 +465,9 @@ int PS4_SYSV_ABI sceNetConfigWlanSetDeviceConfig() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetConnect(OrbisNetId s, const OrbisNetSockaddr* addr, u32 addrlen) {
|
int PS4_SYSV_ABI sceNetConnect() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_connect(s, addr, addrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetControl() {
|
int PS4_SYSV_ABI sceNetControl() {
|
||||||
|
@ -759,15 +640,8 @@ int PS4_SYSV_ABI sceNetGetIfnameNumList() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetMacAddress(Libraries::NetCtl::OrbisNetEtherAddr* addr, int flags) {
|
int PS4_SYSV_ABI sceNetGetMacAddress() {
|
||||||
if (addr == nullptr) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
LOG_ERROR(Lib_Net, "addr is null!");
|
|
||||||
return ORBIS_NET_EINVAL;
|
|
||||||
}
|
|
||||||
auto* netinfo = Common::Singleton<NetUtil::NetUtilInternal>::Instance();
|
|
||||||
netinfo->RetrieveEthernetAddr();
|
|
||||||
memcpy(addr->data, netinfo->GetEthernetAddr().data(), 6);
|
|
||||||
|
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,46 +655,9 @@ int PS4_SYSV_ABI sceNetGetNameToIndex() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetpeername(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sceNetGetpeername() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_getpeername(s, addr, paddrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetRandom() {
|
int PS4_SYSV_ABI sceNetGetRandom() {
|
||||||
|
@ -844,87 +681,13 @@ int PS4_SYSV_ABI sceNetGetSockInfo6() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
int PS4_SYSV_ABI sceNetGetsockname(OrbisNetId s, OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_getsockname(s, addr, paddrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
int PS4_SYSV_ABI sceNetGetsockopt(OrbisNetId s, int level, int optname, void* optval, u32* optlen) {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_getsockopt(s, level, optname, optval, optlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetGetStatisticsInfo() {
|
int PS4_SYSV_ABI sceNetGetStatisticsInfo() {
|
||||||
|
@ -1018,46 +781,9 @@ int PS4_SYSV_ABI sceNetIoctl() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetListen(OrbisNetId s, int backlog) {
|
int PS4_SYSV_ABI sceNetListen() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_listen(s, backlog);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetMemoryAllocate() {
|
int PS4_SYSV_ABI sceNetMemoryAllocate() {
|
||||||
|
@ -1103,131 +829,20 @@ int PS4_SYSV_ABI sceNetPppoeStop() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, u64 len, int flags) {
|
int PS4_SYSV_ABI sceNetRecv() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_recvfrom(s, buf, len, flags | 0x40000000, nullptr, 0);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags,
|
||||||
|
OrbisNetSockaddr* addr, u32* paddrlen) {
|
||||||
// Convert to positive error for comparison
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
return ORBIS_OK;
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry if interrupted
|
int PS4_SYSV_ABI sceNetRecvmsg() {
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr,
|
|
||||||
u32* paddrlen) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_recvfrom(s, buf, len, flags | 0x40000000, addr, paddrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_recvmsg(s, msg, flags | 0x40000000);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetResolverAbort() {
|
int PS4_SYSV_ABI sceNetResolverAbort() {
|
||||||
|
@ -1300,131 +915,19 @@ int PS4_SYSV_ABI sceNetResolverStartNtoaMultipleRecordsEx() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSend(OrbisNetId s, const void* buf, u64 len, int flags) {
|
int PS4_SYSV_ABI sceNetSend() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_sendto(s, buf, len, flags | 0x40020000, nullptr, 0);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
int PS4_SYSV_ABI sceNetSendmsg() {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
// Convert to positive error for comparison
|
return ORBIS_OK;
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry if interrupted
|
int PS4_SYSV_ABI sceNetSendto() {
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_sendmsg(s, msg, flags | 0x40020000);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSendto(OrbisNetId s, const void* buf, u64 len, int flags,
|
|
||||||
const OrbisNetSockaddr* addr, u32 addrlen) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_sendto(s, buf, len, flags | 0x40020000, addr, addrlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSetDns6Info() {
|
int PS4_SYSV_ABI sceNetSetDns6Info() {
|
||||||
|
@ -1447,47 +950,9 @@ int PS4_SYSV_ABI sceNetSetDnsInfoToKernel() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSetsockopt(OrbisNetId s, int level, int optname, const void* optval,
|
int PS4_SYSV_ABI sceNetSetsockopt() {
|
||||||
u32 optlen) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
if (!g_isNetInitialized) {
|
return ORBIS_OK;
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_setsockopt(s, level, optname, optval, optlen);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetShowIfconfig() {
|
int PS4_SYSV_ABI sceNetShowIfconfig() {
|
||||||
|
@ -1570,172 +1035,24 @@ int PS4_SYSV_ABI sceNetShowRouteWithMemory() {
|
||||||
return ORBIS_OK;
|
return ORBIS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetShutdown(OrbisNetId s, int how) {
|
int PS4_SYSV_ABI sceNetShutdown() {
|
||||||
if (!g_isNetInitialized) {
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_shutdown(s, how);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
int PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
// Convert to positive error for comparison
|
return ORBIS_OK;
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retry if interrupted
|
int PS4_SYSV_ABI sceNetSocketAbort() {
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
|
return ORBIS_OK;
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
int PS4_SYSV_ABI sceNetSocketClose() {
|
||||||
|
LOG_ERROR(Lib_Net, "(STUBBED) called");
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
return ORBIS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
OrbisNetId PS4_SYSV_ABI sceNetSocket(const char* name, int family, int type, int protocol) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_socketex(name, family, type, protocol);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSocketAbort(OrbisNetId s, int flags) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_netabort(s, flags);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSocketClose(OrbisNetId s) {
|
|
||||||
if (!g_isNetInitialized) {
|
|
||||||
return ORBIS_NET_ERROR_ENOTINIT;
|
|
||||||
}
|
|
||||||
int result;
|
|
||||||
int err;
|
|
||||||
int positiveErr;
|
|
||||||
|
|
||||||
do {
|
|
||||||
result = sys_socketclose(s);
|
|
||||||
|
|
||||||
if (result >= 0) {
|
|
||||||
return result; // Success
|
|
||||||
}
|
|
||||||
|
|
||||||
err = *Libraries::Kernel::__Error(); // Standard errno
|
|
||||||
|
|
||||||
// Convert to positive error for comparison
|
|
||||||
int positiveErr = (err < 0) ? -err : err;
|
|
||||||
|
|
||||||
if ((positiveErr & 0xfff0000) != 0) {
|
|
||||||
// Unknown/fatal error range
|
|
||||||
*sceNetErrnoLoc() = ORBIS_NET_ERETURN;
|
|
||||||
return -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry if interrupted
|
|
||||||
} while (positiveErr == ORBIS_NET_EINTR);
|
|
||||||
|
|
||||||
if (positiveErr == ORBIS_NET_EADDRINUSE) {
|
|
||||||
result = -ORBIS_NET_EBADF;
|
|
||||||
} else if (positiveErr == ORBIS_NET_EALREADY) {
|
|
||||||
result = -ORBIS_NET_EINTR;
|
|
||||||
} else {
|
|
||||||
result = -positiveErr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*sceNetErrnoLoc() = -result;
|
|
||||||
|
|
||||||
return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int PS4_SYSV_ABI sceNetSyncCreate() {
|
int PS4_SYSV_ABI sceNetSyncCreate() {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue