mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
Merge branch 'shadps4-emu:main' into ukrainian-localization
This commit is contained in:
commit
db99285f8e
@ -10,7 +10,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
|
||||
fi
|
||||
|
||||
# Default clang-format points to default 3.5 version one
|
||||
CLANG_FORMAT=clang-format-17
|
||||
CLANG_FORMAT=clang-format-18
|
||||
$CLANG_FORMAT --version
|
||||
|
||||
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
||||
|
55
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
Normal file
55
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Application Bug Report
|
||||
description: Problem with the application itself (ie. bad file path handling, UX issue)
|
||||
title: "[APP BUG]: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
**Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only.
|
||||
If you have a support request or are unsure about the nature of your issue please contact us on [discord](https://discord.gg/bFJxfftGW6).**
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
Do not create issues involving software piracy, our rules specifically prohibit this. Otherwise your issue will be closed and you will be banned in this repository.
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
- label: I am using an official build obtained from [releases](https://github.com/shadps4-emu/shadPS4/releases) or updated one of those builds using its in-app updater.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: "A clear and concise description of what the bug is"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: "Detailed steps to reproduce the behavior"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: "A clear and concise description of what you expected to happen"
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Specify OS Version
|
||||
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
||||
validations:
|
||||
required: true
|
10
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
10
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Discord
|
||||
url: https://discord.gg/bFJxfftGW6
|
||||
about: Get direct support and hang out with us
|
||||
- name: Wiki
|
||||
url: https://github.com/shadps4-emu/shadPS4/wiki
|
||||
about: Information, guides, etc.
|
54
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
Normal file
54
.github/ISSUE_TEMPLATE/feature-request.yaml
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Feature Request
|
||||
description: Suggest a new feature or improve an existing one
|
||||
title: "[Feature Request]: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
Do not create issues involving software piracy, our rules specifically prohibit this. Otherwise your issue will be closed and you will be banned in this repository.
|
||||
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
A concise description of the feature you want
|
||||
|
||||
Include step by step examples of how the feature should work under various circumstances
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reason
|
||||
attributes:
|
||||
label: Reason
|
||||
description: |
|
||||
Give a reason why you want this feature
|
||||
- How will it make things easier for you?
|
||||
- How does this feature help your enjoyment of the emulator?
|
||||
- What does it provide that isn't being provided currently?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: examples
|
||||
attributes:
|
||||
label: Examples
|
||||
description: |
|
||||
Provide examples of the feature as implemented by other software
|
||||
|
||||
Include screenshots or video if you like to help demonstrate how you'd like this feature to work
|
||||
validations:
|
||||
required: false
|
95
.github/ISSUE_TEMPLATE/game-bug-report.yaml
vendored
Normal file
95
.github/ISSUE_TEMPLATE/game-bug-report.yaml
vendored
Normal file
@ -0,0 +1,95 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Docs - https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema
|
||||
name: Game Emulation Bug Report
|
||||
description: Problem in a game (ie. graphical artifacts, crashes, etc.)
|
||||
title: "[GAME BUG]: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
## Important: Read First
|
||||
|
||||
**Please do not make support requests on GitHub. Our issue tracker is for tracking bugs and feature requests only.
|
||||
If you have a support request or are unsure about the nature of your issue please contact us on [discord](https://discord.gg/bFJxfftGW6).**
|
||||
|
||||
This repository does not provide support for modded games. You should perform and test a clean game installation before submitting an issue.
|
||||
|
||||
This repository does not provide support for game patches. If you are having issues with patches please refer to [Cheats and Patches Repository](https://github.com/shadps4-emu/ps4_cheats).
|
||||
|
||||
Before submitting an issue please check [Game Compatibility Repository](https://github.com/shadps4-emu/shadps4-game-compatibility) for the information about the status of the game.
|
||||
|
||||
Please make an effort to make sure your issue isn't already reported.
|
||||
|
||||
Do not create issues involving software piracy, our rules specifically prohibit this. Otherwise your issue will be closed and you will be banned in this repository.
|
||||
- type: checkboxes
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Checklist (we expect you to perform these steps before opening the issue)
|
||||
options:
|
||||
- label: I have searched for a similar issue in this repository and did not find one.
|
||||
required: true
|
||||
- label: I am using an official build obtained from [releases](https://github.com/shadps4-emu/shadPS4/releases) or updated one of those builds using its in-app updater.
|
||||
required: true
|
||||
- label: I have re-dumped the game and performed a clean install without mods and the issue is still present.
|
||||
required: true
|
||||
- label: I have disabled all patches and cheats and the issue is still present.
|
||||
required: true
|
||||
- label: I have all the required [system modules](https://github.com/shadps4-emu/shadps4-game-compatibility?tab=readme-ov-file#informations) installed.
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desc
|
||||
attributes:
|
||||
label: Describe the Bug
|
||||
description: "A clear and concise description of what the bug is"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: repro
|
||||
attributes:
|
||||
label: Reproduction Steps
|
||||
description: "Detailed steps to reproduce the behavior"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Specify OS Version
|
||||
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
||||
validations:
|
||||
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
|
||||
- type: input
|
||||
id: vram
|
||||
attributes:
|
||||
label: Amount of VRAM in GB
|
||||
placeholder: "Example: 8 GB"
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: "Log File"
|
||||
description: Drag and drop the log file here. It can be found by right clicking on a game name -> Open Folder... -> Open Log Folder. Make sure that the log type is set to `sync`.
|
||||
validations:
|
||||
required: true
|
4
.github/linux-appimage-qt.sh
vendored
4
.github/linux-appimage-qt.sh
vendored
@ -27,7 +27,7 @@ chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
|
||||
|
||||
cp -a "$GITHUB_WORKSPACE/build/translations" AppDir/usr/bin
|
||||
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --plugin qt
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/dist/net.shadps4.shadPS4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/src/images/net.shadps4.shadPS4.svg --plugin qt
|
||||
rm AppDir/usr/plugins/multimedia/libgstreamermediaplugin.so
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir --output appimage
|
||||
mv Shadps4-x86_64.AppImage Shadps4-qt.AppImage
|
||||
mv shadPS4-x86_64.AppImage Shadps4-qt.AppImage
|
||||
|
4
.github/linux-appimage-sdl.sh
vendored
4
.github/linux-appimage-sdl.sh
vendored
@ -17,5 +17,5 @@ chmod a+x linuxdeploy-plugin-checkrt-x86_64.sh
|
||||
# Build AppImage
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir
|
||||
./linuxdeploy-plugin-checkrt-x86_64.sh --appdir AppDir
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/.github/shadps4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/.github/shadps4.png --output appimage
|
||||
mv Shadps4-x86_64.AppImage Shadps4-sdl.AppImage
|
||||
./linuxdeploy-x86_64.AppImage --appdir AppDir -d "$GITHUB_WORKSPACE"/dist/net.shadps4.shadPS4.desktop -e "$GITHUB_WORKSPACE"/build/shadps4 -i "$GITHUB_WORKSPACE"/src/images/net.shadps4.shadPS4.svg --output appimage
|
||||
mv shadPS4-x86_64.AppImage Shadps4-sdl.AppImage
|
||||
|
126
.github/workflows/build.yml
vendored
126
.github/workflows/build.yml
vendored
@ -14,14 +14,14 @@ env:
|
||||
|
||||
jobs:
|
||||
reuse:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: fsfe/reuse-action@v4
|
||||
- uses: fsfe/reuse-action@v5
|
||||
|
||||
clang-format:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -30,16 +30,16 @@ jobs:
|
||||
- name: Install
|
||||
run: |
|
||||
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
|
||||
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-17 main'
|
||||
sudo add-apt-repository 'deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-18 main'
|
||||
sudo apt update
|
||||
sudo apt install clang-format-17
|
||||
sudo apt install clang-format-18
|
||||
- name: Build
|
||||
env:
|
||||
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
||||
run: ./.ci/clang-format.sh
|
||||
|
||||
get-info:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
date: ${{ steps.vars.outputs.date }}
|
||||
shorthash: ${{ steps.vars.outputs.shorthash }}
|
||||
@ -57,7 +57,7 @@ jobs:
|
||||
echo "fullhash=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT
|
||||
|
||||
windows-sdl:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2025
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -89,10 +89,10 @@ jobs:
|
||||
arch: amd64
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $env:NUMBER_OF_PROCESSORS
|
||||
|
||||
- name: Upload Windows SDL artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
@ -101,7 +101,7 @@ jobs:
|
||||
path: ${{github.workspace}}/build/shadPS4.exe
|
||||
|
||||
windows-qt:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2025
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -143,10 +143,10 @@ jobs:
|
||||
arch: amd64
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_QT_GUI=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $env:NUMBER_OF_PROCESSORS
|
||||
|
||||
- name: Deploy and Package
|
||||
run: |
|
||||
@ -162,7 +162,7 @@ jobs:
|
||||
path: upload/
|
||||
|
||||
macos-sdl:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -174,11 +174,6 @@ jobs:
|
||||
with:
|
||||
xcode-version: latest
|
||||
|
||||
- name: Install MoltenVK
|
||||
run: |
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
arch -x86_64 /usr/local/bin/brew install molten-vk
|
||||
|
||||
- name: Cache CMake Configuration
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
@ -201,7 +196,7 @@ jobs:
|
||||
variant: sccache
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(sysctl -n hw.ncpu)
|
||||
@ -210,7 +205,7 @@ jobs:
|
||||
run: |
|
||||
mkdir upload
|
||||
mv ${{github.workspace}}/build/shadps4 upload
|
||||
cp $(arch -x86_64 /usr/local/bin/brew --prefix)/opt/molten-vk/lib/libMoltenVK.dylib upload
|
||||
cp ${{github.workspace}}/build/externals/MoltenVK/libMoltenVK.dylib upload
|
||||
tar cf shadps4-macos-sdl.tar.gz -C upload .
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@ -218,7 +213,7 @@ jobs:
|
||||
path: shadps4-macos-sdl.tar.gz
|
||||
|
||||
macos-qt:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-15
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@ -230,11 +225,8 @@ jobs:
|
||||
with:
|
||||
xcode-version: latest
|
||||
|
||||
- name: Install MoltenVK and Setup Qt
|
||||
run: |
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
arch -x86_64 /usr/local/bin/brew install molten-vk
|
||||
- uses: jurplel/install-qt-action@v4
|
||||
- name: Setup Qt
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
version: 6.7.3
|
||||
host: mac
|
||||
@ -265,7 +257,7 @@ jobs:
|
||||
variant: sccache
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DENABLE_QT_GUI=ON -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_OSX_ARCHITECTURES=x86_64 -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE=ON -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(sysctl -n hw.ncpu)
|
||||
@ -312,10 +304,10 @@ jobs:
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -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
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||
|
||||
- name: Package and Upload Linux(ubuntu64) SDL artifact
|
||||
run: |
|
||||
@ -368,10 +360,10 @@ jobs:
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=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
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel3
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||
|
||||
- name: Run AppImage packaging script
|
||||
run: ./.github/linux-appimage-qt.sh
|
||||
@ -384,6 +376,78 @@ jobs:
|
||||
name: shadps4-linux-qt-${{ needs.get-info.outputs.date }}-${{ needs.get-info.outputs.shorthash }}
|
||||
path: Shadps4-qt.AppImage
|
||||
|
||||
linux-sdl-gcc:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- 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 build-essential libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||
|
||||
- name: Cache CMake Configuration
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: ${{ runner.os }}-sdl-gcc-cache-cmake-configuration
|
||||
with:
|
||||
path: |
|
||||
${{github.workspace}}/build
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
restore-keys: |
|
||||
${{ env.cache-name }}-
|
||||
|
||||
- name: Cache CMake Build
|
||||
uses: hendrikmuhs/ccache-action@v1.2.14
|
||||
env:
|
||||
cache-name: ${{ runner.os }}-sdl-gcc-cache-cmake-build
|
||||
with:
|
||||
append-timestamp: false
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', '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_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||
|
||||
linux-qt-gcc:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: get-info
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- 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 build-essential qt6-base-dev qt6-tools-dev qt6-multimedia-dev libasound2-dev libpulse-dev libopenal-dev libudev-dev
|
||||
|
||||
- name: Cache CMake Configuration
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
cache-name: ${{ runner.os }}-qt-gcc-cache-cmake-configuration
|
||||
with:
|
||||
path: |
|
||||
${{github.workspace}}/build
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', 'cmake/**') }}
|
||||
restore-keys: |
|
||||
${{ env.cache-name }}-
|
||||
|
||||
- name: Cache CMake Build
|
||||
uses: hendrikmuhs/ccache-action@v1.2.14
|
||||
env:
|
||||
cache-name: ${{ runner.os }}-qt-gcc-cache-cmake-build
|
||||
with:
|
||||
append-timestamp: false
|
||||
key: ${{ env.cache-name }}-${{ hashFiles('**/CMakeLists.txt', '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 -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
|
||||
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc)
|
||||
|
||||
pre-release:
|
||||
if: github.ref == 'refs/heads/main' && github.repository == 'shadps4-emu/shadPS4' && github.event_name == 'push'
|
||||
needs: [get-info, windows-sdl, windows-qt, macos-sdl, macos-qt, linux-sdl, linux-qt]
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -414,3 +414,7 @@ FodyWeavers.xsd
|
||||
|
||||
# for macOS
|
||||
**/.DS_Store
|
||||
|
||||
# JetBrains
|
||||
.idea
|
||||
cmake-build-*
|
||||
|
17
.gitmodules
vendored
17
.gitmodules
vendored
@ -102,3 +102,20 @@
|
||||
[submodule "externals/LibAtrac9"]
|
||||
path = externals/LibAtrac9
|
||||
url = https://github.com/shadps4-emu/ext-LibAtrac9.git
|
||||
shallow = true
|
||||
[submodule "externals/libpng"]
|
||||
path = externals/libpng
|
||||
url = https://github.com/pnggroup/libpng
|
||||
shallow = true
|
||||
[submodule "externals/MoltenVK/SPIRV-Cross"]
|
||||
path = externals/MoltenVK/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross
|
||||
shallow = true
|
||||
[submodule "externals/MoltenVK/MoltenVK"]
|
||||
path = externals/MoltenVK/MoltenVK
|
||||
url = https://github.com/KhronosGroup/MoltenVK
|
||||
shallow = true
|
||||
[submodule "externals/MoltenVK/cereal"]
|
||||
path = externals/MoltenVK/cereal
|
||||
url = https://github.com/USCiLab/cereal
|
||||
shallow = true
|
||||
|
319
CMakeLists.txt
319
CMakeLists.txt
@ -1,7 +1,8 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
cmake_minimum_required(VERSION 3.16.3)
|
||||
# Version 3.24 needed for FetchContent OVERRIDE_FIND_PACKAGE
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 23)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
@ -15,7 +16,7 @@ if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
|
||||
project(shadPS4)
|
||||
project(shadPS4 CXX C ASM)
|
||||
|
||||
# Forcing PIE makes sure that the base address is high enough so that it doesn't clash with the PS4 memory.
|
||||
if(UNIX AND NOT APPLE)
|
||||
@ -31,6 +32,7 @@ endif()
|
||||
|
||||
option(ENABLE_QT_GUI "Enable the Qt GUI. If not selected then the emulator uses a minimal SDL-based UI instead" OFF)
|
||||
option(ENABLE_DISCORD_RPC "Enable the Discord RPC integration" ON)
|
||||
option(ENABLE_UPDATER "Enables the options to updater" ON)
|
||||
|
||||
# First, determine whether to use CMAKE_OSX_ARCHITECTURES or CMAKE_SYSTEM_PROCESSOR.
|
||||
if (APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
@ -104,23 +106,55 @@ git_describe(GIT_DESC --always --long --dirty)
|
||||
git_branch_name(GIT_BRANCH)
|
||||
string(TIMESTAMP BUILD_DATE "%Y-%m-%d %H:%M:%S")
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||
# Try to get the upstream remote and branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref --symbolic-full-name @{u}
|
||||
OUTPUT_VARIABLE GIT_REMOTE_NAME
|
||||
RESULT_VARIABLE GIT_BRANCH_RESULT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Default to origin if there's no upstream set or if the command failed
|
||||
if (GIT_BRANCH_RESULT OR GIT_REMOTE_NAME STREQUAL "")
|
||||
set(GIT_REMOTE_NAME "origin")
|
||||
else()
|
||||
# Extract remote name if the output contains a remote/branch format
|
||||
string(FIND "${GIT_REMOTE_NAME}" "/" INDEX)
|
||||
if (INDEX GREATER -1)
|
||||
string(SUBSTRING "${GIT_REMOTE_NAME}" 0 "${INDEX}" GIT_REMOTE_NAME)
|
||||
else()
|
||||
# If no remote is present (only a branch name), default to origin
|
||||
set(GIT_REMOTE_NAME "origin")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Get remote link
|
||||
execute_process(
|
||||
COMMAND git config --get remote.${GIT_REMOTE_NAME}.url
|
||||
OUTPUT_VARIABLE GIT_REMOTE_URL
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||
|
||||
find_package(Boost 1.84.0 CONFIG)
|
||||
find_package(FFmpeg 5.1.2 MODULE)
|
||||
find_package(fmt 10.2.0 CONFIG)
|
||||
find_package(glslang 14.2.0 CONFIG)
|
||||
find_package(glslang 15 CONFIG)
|
||||
find_package(half 1.12.0 MODULE)
|
||||
find_package(magic_enum 0.9.6 CONFIG)
|
||||
find_package(magic_enum 0.9.7 CONFIG)
|
||||
find_package(PNG 1.6 MODULE)
|
||||
find_package(RenderDoc 1.6.0 MODULE)
|
||||
find_package(SDL3 3.1.2 CONFIG)
|
||||
find_package(stb MODULE)
|
||||
find_package(toml11 4.2.0 CONFIG)
|
||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||
find_package(VulkanHeaders 1.3.289 CONFIG)
|
||||
find_package(VulkanHeaders 1.4.305 CONFIG)
|
||||
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
||||
find_package(xbyak 7.07 CONFIG)
|
||||
find_package(xxHash 0.8.2 MODULE)
|
||||
find_package(zlib-ng 2.1.7 MODULE)
|
||||
find_package(ZLIB 1.3 MODULE)
|
||||
find_package(Zydis 5.0.0 CONFIG)
|
||||
find_package(pugixml 1.14 CONFIG)
|
||||
|
||||
@ -175,10 +209,6 @@ if(ENABLE_QT_GUI)
|
||||
qt_add_resources(TRANSLATIONS ${TRANSLATIONS_QRC})
|
||||
endif()
|
||||
|
||||
set(AUDIO_CORE src/audio_core/sdl_audio.cpp
|
||||
src/audio_core/sdl_audio.h
|
||||
)
|
||||
|
||||
set(AJM_LIB src/core/libraries/ajm/ajm.cpp
|
||||
src/core/libraries/ajm/ajm.h
|
||||
src/core/libraries/ajm/ajm_at9.cpp
|
||||
@ -188,6 +218,8 @@ set(AJM_LIB src/core/libraries/ajm/ajm.cpp
|
||||
src/core/libraries/ajm/ajm_context.cpp
|
||||
src/core/libraries/ajm/ajm_context.h
|
||||
src/core/libraries/ajm/ajm_error.h
|
||||
src/core/libraries/ajm/ajm_instance_statistics.cpp
|
||||
src/core/libraries/ajm/ajm_instance_statistics.h
|
||||
src/core/libraries/ajm/ajm_instance.cpp
|
||||
src/core/libraries/ajm/ajm_instance.h
|
||||
src/core/libraries/ajm/ajm_mp3.cpp
|
||||
@ -198,43 +230,64 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp
|
||||
src/core/libraries/audio/audioin.h
|
||||
src/core/libraries/audio/audioout.cpp
|
||||
src/core/libraries/audio/audioout.h
|
||||
src/core/libraries/audio/audioout_backend.h
|
||||
src/core/libraries/audio/audioout_error.h
|
||||
src/core/libraries/audio/sdl_audio.cpp
|
||||
src/core/libraries/ngs2/ngs2.cpp
|
||||
src/core/libraries/ngs2/ngs2.h
|
||||
)
|
||||
|
||||
set(GNM_LIB src/core/libraries/gnmdriver/gnmdriver.cpp
|
||||
src/core/libraries/gnmdriver/gnmdriver.h
|
||||
src/core/libraries/gnmdriver/gnmdriver_init.h
|
||||
src/core/libraries/gnmdriver/gnm_error.h
|
||||
)
|
||||
|
||||
set(KERNEL_LIB src/core/libraries/kernel/event_flag/event_flag.cpp
|
||||
src/core/libraries/kernel/event_flag/event_flag.h
|
||||
src/core/libraries/kernel/event_flag/event_flag_obj.cpp
|
||||
src/core/libraries/kernel/event_flag/event_flag_obj.h
|
||||
set(KERNEL_LIB src/core/libraries/kernel/sync/mutex.cpp
|
||||
src/core/libraries/kernel/sync/mutex.h
|
||||
src/core/libraries/kernel/sync/semaphore.h
|
||||
src/core/libraries/kernel/threads/condvar.cpp
|
||||
src/core/libraries/kernel/threads/event_flag.cpp
|
||||
src/core/libraries/kernel/threads/exception.cpp
|
||||
src/core/libraries/kernel/threads/exception.h
|
||||
src/core/libraries/kernel/threads/mutex.cpp
|
||||
src/core/libraries/kernel/threads/pthread_attr.cpp
|
||||
src/core/libraries/kernel/threads/pthread_clean.cpp
|
||||
src/core/libraries/kernel/threads/pthread.cpp
|
||||
src/core/libraries/kernel/threads/pthread_spec.cpp
|
||||
src/core/libraries/kernel/threads/rwlock.cpp
|
||||
src/core/libraries/kernel/threads/semaphore.cpp
|
||||
src/core/libraries/kernel/threads/keys.cpp
|
||||
src/core/libraries/kernel/threads/threads.h
|
||||
src/core/libraries/kernel/cpu_management.cpp
|
||||
src/core/libraries/kernel/cpu_management.h
|
||||
src/core/libraries/kernel/event_queue.cpp
|
||||
src/core/libraries/kernel/event_queue.h
|
||||
src/core/libraries/kernel/event_queues.cpp
|
||||
src/core/libraries/kernel/event_queues.h
|
||||
src/core/libraries/kernel/threads/sleepq.cpp
|
||||
src/core/libraries/kernel/threads/sleepq.h
|
||||
src/core/libraries/kernel/threads/stack.cpp
|
||||
src/core/libraries/kernel/threads/tcb.cpp
|
||||
src/core/libraries/kernel/threads/pthread.h
|
||||
src/core/libraries/kernel/threads/thread_state.cpp
|
||||
src/core/libraries/kernel/threads/thread_state.h
|
||||
src/core/libraries/kernel/process.cpp
|
||||
src/core/libraries/kernel/process.h
|
||||
src/core/libraries/kernel/equeue.cpp
|
||||
src/core/libraries/kernel/equeue.h
|
||||
src/core/libraries/kernel/file_system.cpp
|
||||
src/core/libraries/kernel/file_system.h
|
||||
src/core/libraries/kernel/libkernel.cpp
|
||||
src/core/libraries/kernel/libkernel.h
|
||||
src/core/libraries/kernel/memory_management.cpp
|
||||
src/core/libraries/kernel/memory_management.h
|
||||
src/core/libraries/kernel/thread_management.cpp
|
||||
src/core/libraries/kernel/thread_management.h
|
||||
src/core/libraries/kernel/time_management.cpp
|
||||
src/core/libraries/kernel/time_management.h
|
||||
src/core/libraries/kernel/kernel.cpp
|
||||
src/core/libraries/kernel/kernel.h
|
||||
src/core/libraries/kernel/memory.cpp
|
||||
src/core/libraries/kernel/memory.h
|
||||
src/core/libraries/kernel/threads.cpp
|
||||
src/core/libraries/kernel/threads.h
|
||||
src/core/libraries/kernel/time.cpp
|
||||
src/core/libraries/kernel/time.h
|
||||
src/core/libraries/kernel/orbis_error.h
|
||||
src/core/libraries/kernel/posix_error.h
|
||||
src/core/libraries/kernel/aio.cpp
|
||||
src/core/libraries/kernel/aio.h
|
||||
)
|
||||
|
||||
set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
||||
src/core/libraries/network/http.h
|
||||
src/core/libraries/network/http2.cpp
|
||||
src/core/libraries/network/http2.h
|
||||
src/core/libraries/network/net.cpp
|
||||
src/core/libraries/network/netctl.cpp
|
||||
src/core/libraries/network/netctl.h
|
||||
@ -244,6 +297,23 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp
|
||||
src/core/libraries/network/net.h
|
||||
src/core/libraries/network/ssl.cpp
|
||||
src/core/libraries/network/ssl.h
|
||||
src/core/libraries/network/ssl2.cpp
|
||||
src/core/libraries/network/ssl2.h
|
||||
)
|
||||
|
||||
set(AVPLAYER_LIB src/core/libraries/avplayer/avplayer_common.cpp
|
||||
src/core/libraries/avplayer/avplayer_common.h
|
||||
src/core/libraries/avplayer/avplayer_file_streamer.cpp
|
||||
src/core/libraries/avplayer/avplayer_file_streamer.h
|
||||
src/core/libraries/avplayer/avplayer_impl.cpp
|
||||
src/core/libraries/avplayer/avplayer_impl.h
|
||||
src/core/libraries/avplayer/avplayer_source.cpp
|
||||
src/core/libraries/avplayer/avplayer_source.h
|
||||
src/core/libraries/avplayer/avplayer_state.cpp
|
||||
src/core/libraries/avplayer/avplayer_state.h
|
||||
src/core/libraries/avplayer/avplayer.cpp
|
||||
src/core/libraries/avplayer/avplayer.h
|
||||
src/core/libraries/avplayer/avplayer_error.h
|
||||
)
|
||||
|
||||
set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||
@ -267,30 +337,22 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||
src/core/libraries/save_data/dialog/savedatadialog_ui.h
|
||||
src/core/libraries/system/sysmodule.cpp
|
||||
src/core/libraries/system/sysmodule.h
|
||||
src/core/libraries/system/system_error.h
|
||||
src/core/libraries/system/systemservice.cpp
|
||||
src/core/libraries/system/systemservice.h
|
||||
src/core/libraries/system/systemservice_error.h
|
||||
src/core/libraries/system/userservice.cpp
|
||||
src/core/libraries/system/userservice.h
|
||||
src/core/libraries/system/userservice_error.h
|
||||
src/core/libraries/app_content/app_content.cpp
|
||||
src/core/libraries/app_content/app_content.h
|
||||
src/core/libraries/app_content/app_content_error.h
|
||||
src/core/libraries/rtc/rtc.cpp
|
||||
src/core/libraries/rtc/rtc.h
|
||||
src/core/libraries/rtc/rtc_error.h
|
||||
src/core/libraries/disc_map/disc_map.cpp
|
||||
src/core/libraries/disc_map/disc_map.h
|
||||
src/core/libraries/disc_map/disc_map_codes.h
|
||||
src/core/libraries/avplayer/avplayer_common.cpp
|
||||
src/core/libraries/avplayer/avplayer_common.h
|
||||
src/core/libraries/avplayer/avplayer_file_streamer.cpp
|
||||
src/core/libraries/avplayer/avplayer_file_streamer.h
|
||||
src/core/libraries/avplayer/avplayer_impl.cpp
|
||||
src/core/libraries/avplayer/avplayer_impl.h
|
||||
src/core/libraries/avplayer/avplayer_source.cpp
|
||||
src/core/libraries/avplayer/avplayer_source.h
|
||||
src/core/libraries/avplayer/avplayer_state.cpp
|
||||
src/core/libraries/avplayer/avplayer_state.h
|
||||
src/core/libraries/avplayer/avplayer.cpp
|
||||
src/core/libraries/avplayer/avplayer.h
|
||||
src/core/libraries/ngs2/ngs2.cpp
|
||||
src/core/libraries/ngs2/ngs2.h
|
||||
src/core/libraries/ngs2/ngs2_error.h
|
||||
@ -308,6 +370,12 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
||||
src/core/libraries/remote_play/remoteplay.h
|
||||
src/core/libraries/share_play/shareplay.cpp
|
||||
src/core/libraries/share_play/shareplay.h
|
||||
src/core/libraries/razor_cpu/razor_cpu.cpp
|
||||
src/core/libraries/razor_cpu/razor_cpu.h
|
||||
src/core/libraries/mouse/mouse.cpp
|
||||
src/core/libraries/mouse/mouse.h
|
||||
src/core/libraries/web_browser_dialog/webbrowserdialog.cpp
|
||||
src/core/libraries/web_browser_dialog/webbrowserdialog.h
|
||||
)
|
||||
|
||||
set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||
@ -315,6 +383,7 @@ set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h
|
||||
src/core/libraries/videoout/driver.h
|
||||
src/core/libraries/videoout/video_out.cpp
|
||||
src/core/libraries/videoout/video_out.h
|
||||
src/core/libraries/videoout/videoout_error.h
|
||||
)
|
||||
|
||||
set(LIBC_SOURCES src/core/libraries/libc_internal/libc_internal.cpp
|
||||
@ -332,18 +401,28 @@ set(IME_LIB src/core/libraries/ime/error_dialog.cpp
|
||||
src/core/libraries/ime/ime_ui.h
|
||||
src/core/libraries/ime/ime.cpp
|
||||
src/core/libraries/ime/ime.h
|
||||
src/core/libraries/ime/ime_error.h
|
||||
)
|
||||
|
||||
set(PAD_LIB src/core/libraries/pad/pad.cpp
|
||||
src/core/libraries/pad/pad.h
|
||||
src/core/libraries/pad/pad_errors.h
|
||||
)
|
||||
|
||||
set(PNG_LIB src/core/libraries/libpng/pngdec.cpp
|
||||
src/core/libraries/libpng/pngdec.h
|
||||
src/core/libraries/libpng/pngdec_error.h
|
||||
)
|
||||
|
||||
set(JPEG_LIB src/core/libraries/jpeg/jpeg_error.h
|
||||
src/core/libraries/jpeg/jpegenc.cpp
|
||||
src/core/libraries/jpeg/jpegenc.h
|
||||
)
|
||||
|
||||
set(PLAYGO_LIB src/core/libraries/playgo/playgo.cpp
|
||||
src/core/libraries/playgo/playgo.h
|
||||
src/core/libraries/playgo/playgo_dialog.cpp
|
||||
src/core/libraries/playgo/playgo_dialog.h
|
||||
src/core/libraries/playgo/playgo_types.h
|
||||
)
|
||||
|
||||
@ -356,8 +435,10 @@ set(USBD_LIB src/core/libraries/usbd/usbd.cpp
|
||||
src/core/libraries/usbd/usbd.h
|
||||
)
|
||||
|
||||
set(FIBER_LIB src/core/libraries/fiber/fiber.cpp
|
||||
set(FIBER_LIB src/core/libraries/fiber/fiber_context.s
|
||||
src/core/libraries/fiber/fiber.cpp
|
||||
src/core/libraries/fiber/fiber.h
|
||||
src/core/libraries/fiber/fiber_error.h
|
||||
)
|
||||
|
||||
set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
|
||||
@ -365,9 +446,16 @@ set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp
|
||||
src/core/libraries/videodec/videodec2.cpp
|
||||
src/core/libraries/videodec/videodec2.h
|
||||
src/core/libraries/videodec/videodec2_avc.h
|
||||
src/core/libraries/videodec/videodec.cpp
|
||||
src/core/libraries/videodec/videodec.h
|
||||
src/core/libraries/videodec/videodec_error.h
|
||||
src/core/libraries/videodec/videodec_impl.cpp
|
||||
src/core/libraries/videodec/videodec_impl.h
|
||||
)
|
||||
|
||||
set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
||||
set(NP_LIBS src/core/libraries/np_common/np_common.cpp
|
||||
src/core/libraries/np_common/np_common.h
|
||||
src/core/libraries/np_manager/np_manager.cpp
|
||||
src/core/libraries/np_manager/np_manager.h
|
||||
src/core/libraries/np_score/np_score.cpp
|
||||
src/core/libraries/np_score/np_score.h
|
||||
@ -375,10 +463,22 @@ set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp
|
||||
src/core/libraries/np_trophy/np_trophy.h
|
||||
src/core/libraries/np_trophy/trophy_ui.cpp
|
||||
src/core/libraries/np_trophy/trophy_ui.h
|
||||
src/core/libraries/np_trophy/np_trophy_error.h
|
||||
src/core/libraries/np_web_api/np_web_api.cpp
|
||||
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.h
|
||||
)
|
||||
|
||||
set(ZLIB_LIB src/core/libraries/zlib/zlib.cpp
|
||||
src/core/libraries/zlib/zlib_sce.h
|
||||
src/core/libraries/zlib/zlib_error.h
|
||||
)
|
||||
|
||||
set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
|
||||
src/core/libraries/screenshot/screenshot.h
|
||||
src/core/libraries/move/move.cpp
|
||||
src/core/libraries/move/move.h
|
||||
)
|
||||
|
||||
set(DEV_TOOLS src/core/devtools/layer.cpp
|
||||
@ -396,10 +496,14 @@ set(DEV_TOOLS src/core/devtools/layer.cpp
|
||||
src/core/devtools/widget/frame_graph.cpp
|
||||
src/core/devtools/widget/frame_graph.h
|
||||
src/core/devtools/widget/imgui_memory_editor.h
|
||||
src/core/devtools/widget/memory_map.cpp
|
||||
src/core/devtools/widget/memory_map.h
|
||||
src/core/devtools/widget/reg_popup.cpp
|
||||
src/core/devtools/widget/reg_popup.h
|
||||
src/core/devtools/widget/reg_view.cpp
|
||||
src/core/devtools/widget/reg_view.h
|
||||
src/core/devtools/widget/shader_list.cpp
|
||||
src/core/devtools/widget/shader_list.h
|
||||
src/core/devtools/widget/text_editor.cpp
|
||||
src/core/devtools/widget/text_editor.h
|
||||
)
|
||||
@ -448,7 +552,12 @@ set(COMMON src/common/logging/backend.cpp
|
||||
src/common/signal_context.h
|
||||
src/common/signal_context.cpp
|
||||
src/common/singleton.h
|
||||
src/common/slab_heap.h
|
||||
src/common/slot_vector.h
|
||||
src/common/spin_lock.cpp
|
||||
src/common/spin_lock.h
|
||||
src/common/stb.cpp
|
||||
src/common/stb.h
|
||||
src/common/string_util.cpp
|
||||
src/common/string_util.h
|
||||
src/common/thread.cpp
|
||||
@ -456,6 +565,7 @@ set(COMMON src/common/logging/backend.cpp
|
||||
src/common/types.h
|
||||
src/common/uint128.h
|
||||
src/common/unique_function.h
|
||||
src/common/va_ctx.h
|
||||
src/common/version.h
|
||||
src/common/ntapi.h
|
||||
src/common/ntapi.cpp
|
||||
@ -463,7 +573,7 @@ set(COMMON src/common/logging/backend.cpp
|
||||
src/common/number_utils.cpp
|
||||
src/common/memory_patcher.h
|
||||
src/common/memory_patcher.cpp
|
||||
src/common/scm_rev.cpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp
|
||||
src/common/scm_rev.h
|
||||
)
|
||||
|
||||
@ -480,6 +590,22 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||
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.h
|
||||
src/core/devices/ioccom.h
|
||||
src/core/devices/logger.cpp
|
||||
src/core/devices/logger.h
|
||||
src/core/devices/nop_device.h
|
||||
src/core/devices/console_device.cpp
|
||||
src/core/devices/console_device.h
|
||||
src/core/devices/deci_tty6_device.cpp
|
||||
src/core/devices/deci_tty6_device.h
|
||||
src/core/devices/random_device.cpp
|
||||
src/core/devices/random_device.h
|
||||
src/core/devices/urandom_device.cpp
|
||||
src/core/devices/urandom_device.h
|
||||
src/core/devices/srandom_device.cpp
|
||||
src/core/devices/srandom_device.h
|
||||
src/core/file_format/pfs.h
|
||||
src/core/file_format/pkg.cpp
|
||||
src/core/file_format/pkg.h
|
||||
@ -503,10 +629,10 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||
src/core/loader/elf.h
|
||||
src/core/loader/symbols_resolver.h
|
||||
src/core/loader/symbols_resolver.cpp
|
||||
src/core/libraries/error_codes.h
|
||||
src/core/libraries/libs.h
|
||||
src/core/libraries/libs.cpp
|
||||
${AJM_LIB}
|
||||
${AVPLAYER_LIB}
|
||||
${AUDIO_LIB}
|
||||
${GNM_LIB}
|
||||
${KERNEL_LIB}
|
||||
@ -517,9 +643,11 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||
${VIDEOOUT_LIB}
|
||||
${NP_LIBS}
|
||||
${PNG_LIB}
|
||||
${JPEG_LIB}
|
||||
${PLAYGO_LIB}
|
||||
${RANDOM_LIB}
|
||||
${USBD_LIB}
|
||||
${ZLIB_LIB}
|
||||
${MISC_LIBS}
|
||||
${IME_LIB}
|
||||
${FIBER_LIB}
|
||||
@ -536,10 +664,10 @@ set(CORE src/core/aerolib/stubs.cpp
|
||||
src/core/platform.h
|
||||
src/core/signals.cpp
|
||||
src/core/signals.h
|
||||
src/core/thread.cpp
|
||||
src/core/thread.h
|
||||
src/core/tls.cpp
|
||||
src/core/tls.h
|
||||
src/core/virtual_memory.cpp
|
||||
src/core/virtual_memory.h
|
||||
)
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
@ -570,6 +698,8 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_instructions.h
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_integer.cpp
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_logical.cpp
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.cpp
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_quad_rect.h
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_select.cpp
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_shared_memory.cpp
|
||||
src/shader_recompiler/backend/spirv/emit_spirv_special.cpp
|
||||
@ -604,12 +734,14 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||
src/shader_recompiler/ir/passes/constant_propagation_pass.cpp
|
||||
src/shader_recompiler/ir/passes/dead_code_elimination_pass.cpp
|
||||
src/shader_recompiler/ir/passes/flatten_extended_userdata_pass.cpp
|
||||
src/shader_recompiler/ir/passes/hull_shader_transform.cpp
|
||||
src/shader_recompiler/ir/passes/identity_removal_pass.cpp
|
||||
src/shader_recompiler/ir/passes/ir_passes.h
|
||||
src/shader_recompiler/ir/passes/lower_shared_mem_to_registers.cpp
|
||||
src/shader_recompiler/ir/passes/resource_tracking_pass.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/shared_memory_barrier_pass.cpp
|
||||
src/shader_recompiler/ir/passes/ssa_rewrite_pass.cpp
|
||||
src/shader_recompiler/ir/abstract_syntax_list.h
|
||||
src/shader_recompiler/ir/attribute.cpp
|
||||
@ -623,10 +755,13 @@ set(SHADER_RECOMPILER src/shader_recompiler/exception.h
|
||||
src/shader_recompiler/ir/opcodes.cpp
|
||||
src/shader_recompiler/ir/opcodes.h
|
||||
src/shader_recompiler/ir/opcodes.inc
|
||||
src/shader_recompiler/ir/patch.cpp
|
||||
src/shader_recompiler/ir/patch.h
|
||||
src/shader_recompiler/ir/post_order.cpp
|
||||
src/shader_recompiler/ir/post_order.h
|
||||
src/shader_recompiler/ir/program.cpp
|
||||
src/shader_recompiler/ir/program.h
|
||||
src/shader_recompiler/ir/reinterpret.h
|
||||
src/shader_recompiler/ir/reg.h
|
||||
src/shader_recompiler/ir/type.cpp
|
||||
src/shader_recompiler/ir/type.h
|
||||
@ -652,14 +787,10 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||
src/video_core/buffer_cache/word_manager.h
|
||||
src/video_core/renderer_vulkan/liverpool_to_vk.cpp
|
||||
src/video_core/renderer_vulkan/liverpool_to_vk.h
|
||||
src/video_core/renderer_vulkan/renderer_vulkan.cpp
|
||||
src/video_core/renderer_vulkan/renderer_vulkan.h
|
||||
src/video_core/renderer_vulkan/vk_common.cpp
|
||||
src/video_core/renderer_vulkan/vk_common.h
|
||||
src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
|
||||
src/video_core/renderer_vulkan/vk_compute_pipeline.h
|
||||
src/video_core/renderer_vulkan/vk_descriptor_update_queue.cpp
|
||||
src/video_core/renderer_vulkan/vk_descriptor_update_queue.h
|
||||
src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
|
||||
src/video_core/renderer_vulkan/vk_graphics_pipeline.h
|
||||
src/video_core/renderer_vulkan/vk_instance.cpp
|
||||
@ -672,12 +803,16 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
|
||||
src/video_core/renderer_vulkan/vk_pipeline_common.h
|
||||
src/video_core/renderer_vulkan/vk_platform.cpp
|
||||
src/video_core/renderer_vulkan/vk_platform.h
|
||||
src/video_core/renderer_vulkan/vk_presenter.cpp
|
||||
src/video_core/renderer_vulkan/vk_presenter.h
|
||||
src/video_core/renderer_vulkan/vk_rasterizer.cpp
|
||||
src/video_core/renderer_vulkan/vk_rasterizer.h
|
||||
src/video_core/renderer_vulkan/vk_resource_pool.cpp
|
||||
src/video_core/renderer_vulkan/vk_resource_pool.h
|
||||
src/video_core/renderer_vulkan/vk_scheduler.cpp
|
||||
src/video_core/renderer_vulkan/vk_scheduler.h
|
||||
src/video_core/renderer_vulkan/vk_shader_hle.cpp
|
||||
src/video_core/renderer_vulkan/vk_shader_hle.h
|
||||
src/video_core/renderer_vulkan/vk_shader_util.cpp
|
||||
src/video_core/renderer_vulkan/vk_shader_util.h
|
||||
src/video_core/renderer_vulkan/vk_swapchain.cpp
|
||||
@ -719,6 +854,10 @@ set(IMGUI src/imgui/imgui_config.h
|
||||
|
||||
set(INPUT src/input/controller.cpp
|
||||
src/input/controller.h
|
||||
src/input/input_handler.cpp
|
||||
src/input/input_handler.h
|
||||
src/input/input_mouse.cpp
|
||||
src/input/input_mouse.h
|
||||
)
|
||||
|
||||
set(EMULATOR src/emulator.cpp
|
||||
@ -732,6 +871,12 @@ set(EMULATOR src/emulator.cpp
|
||||
if(ENABLE_QT_GUI)
|
||||
qt_add_resources(RESOURCE_FILES src/shadps4.qrc)
|
||||
|
||||
if (ENABLE_UPDATER)
|
||||
set(UPDATER src/qt_gui/check_update.cpp
|
||||
src/qt_gui/check_update.h
|
||||
)
|
||||
endif()
|
||||
|
||||
set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||
src/qt_gui/about_dialog.h
|
||||
src/qt_gui/about_dialog.ui
|
||||
@ -739,8 +884,8 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||
src/qt_gui/background_music_player.h
|
||||
src/qt_gui/cheats_patches.cpp
|
||||
src/qt_gui/cheats_patches.h
|
||||
src/qt_gui/check_update.cpp
|
||||
src/qt_gui/check_update.h
|
||||
src/qt_gui/compatibility_info.cpp
|
||||
src/qt_gui/compatibility_info.h
|
||||
src/qt_gui/main_window_ui.h
|
||||
src/qt_gui/main_window.cpp
|
||||
src/qt_gui/main_window.h
|
||||
@ -762,6 +907,10 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||
src/qt_gui/trophy_viewer.h
|
||||
src/qt_gui/elf_viewer.cpp
|
||||
src/qt_gui/elf_viewer.h
|
||||
src/qt_gui/kbm_config_dialog.cpp
|
||||
src/qt_gui/kbm_config_dialog.h
|
||||
src/qt_gui/kbm_help_dialog.cpp
|
||||
src/qt_gui/kbm_help_dialog.h
|
||||
src/qt_gui/main_window_themes.cpp
|
||||
src/qt_gui/main_window_themes.h
|
||||
src/qt_gui/settings_dialog.cpp
|
||||
@ -771,6 +920,7 @@ set(QT_GUI src/qt_gui/about_dialog.cpp
|
||||
${EMULATOR}
|
||||
${RESOURCE_FILES}
|
||||
${TRANSLATIONS}
|
||||
${UPDATER}
|
||||
)
|
||||
endif()
|
||||
|
||||
@ -807,20 +957,41 @@ endif()
|
||||
|
||||
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)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::SPIRV glslang::glslang SDL3::SDL3 pugixml::pugixml)
|
||||
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)
|
||||
|
||||
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")
|
||||
|
||||
if (ENABLE_DISCORD_RPC)
|
||||
target_compile_definitions(shadps4 PRIVATE ENABLE_DISCORD_RPC)
|
||||
endif()
|
||||
|
||||
# Optional due to https://github.com/shadps4-emu/shadPS4/issues/1704
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND ENABLE_USERFAULTFD)
|
||||
target_compile_definitions(shadps4 PRIVATE ENABLE_USERFAULTFD)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
option(USE_SYSTEM_VULKAN_LOADER "Enables using the system Vulkan loader instead of directly linking with MoltenVK. Useful for loading validation layers." OFF)
|
||||
if (USE_SYSTEM_VULKAN_LOADER)
|
||||
target_compile_definitions(shadps4 PRIVATE USE_SYSTEM_VULKAN_LOADER=1)
|
||||
if (ENABLE_QT_GUI)
|
||||
# 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(MVK_ICD ${CMAKE_CURRENT_SOURCE_DIR}/externals/MoltenVK/MoltenVK_icd.json)
|
||||
target_sources(shadps4 PRIVATE ${MVK_ICD})
|
||||
set_source_files_properties(${MVK_ICD} PROPERTIES MACOSX_PACKAGE_LOCATION Resources/vulkan/icd.d)
|
||||
|
||||
set(MVK_DYLIB_SRC ${CMAKE_CURRENT_BINARY_DIR}/externals/MoltenVK/libMoltenVK.dylib)
|
||||
set(MVK_DYLIB_DST ${CMAKE_CURRENT_BINARY_DIR}/shadps4.app/Contents/Frameworks/libMoltenVK.dylib)
|
||||
add_custom_command(
|
||||
OUTPUT ${MVK_DYLIB_DST}
|
||||
DEPENDS ${MVK_DYLIB_SRC}
|
||||
COMMAND cmake -E copy ${MVK_DYLIB_SRC} ${MVK_DYLIB_DST})
|
||||
add_custom_target(CopyMoltenVK DEPENDS ${MVK_DYLIB_DST})
|
||||
add_dependencies(CopyMoltenVK MoltenVK)
|
||||
add_dependencies(shadps4 CopyMoltenVK)
|
||||
set_property(TARGET shadps4 APPEND PROPERTY BUILD_RPATH "@executable_path/../Frameworks")
|
||||
else()
|
||||
# Link MoltenVK for Vulkan support
|
||||
find_library(MOLTENVK MoltenVK REQUIRED)
|
||||
target_link_libraries(shadps4 PRIVATE ${MOLTENVK})
|
||||
# For non-bundled SDL build, just do a normal library link.
|
||||
target_link_libraries(shadps4 PRIVATE MoltenVK)
|
||||
endif()
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
@ -837,14 +1008,17 @@ if (NOT ENABLE_QT_GUI)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND MSVC)
|
||||
target_link_libraries(shadps4 PRIVATE cryptoppwin zlib-ng::zlib)
|
||||
target_link_libraries(shadps4 PRIVATE cryptoppwin)
|
||||
else()
|
||||
target_link_libraries(shadps4 PRIVATE cryptopp::cryptopp zlib-ng::zlib)
|
||||
target_link_libraries(shadps4 PRIVATE cryptopp::cryptopp)
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT_GUI)
|
||||
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network Qt6::Multimedia)
|
||||
add_definitions(-DENABLE_QT_GUI)
|
||||
target_link_libraries(shadps4 PRIVATE Qt6::Widgets Qt6::Concurrent Qt6::Network Qt6::Multimedia)
|
||||
add_definitions(-DENABLE_QT_GUI)
|
||||
if (ENABLE_UPDATER)
|
||||
add_definitions(-DENABLE_UPDATER)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
@ -908,7 +1082,10 @@ if (ENABLE_QT_GUI)
|
||||
set_target_properties(shadps4 PROPERTIES
|
||||
# WIN32_EXECUTABLE ON
|
||||
MACOSX_BUNDLE ON
|
||||
MACOSX_BUNDLE_ICON_FILE shadPS4.icns)
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in"
|
||||
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.4.1"
|
||||
)
|
||||
|
||||
set_source_files_properties(src/images/shadPS4.icns PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
@ -930,6 +1107,8 @@ endif()
|
||||
install(TARGETS shadps4 BUNDLE DESTINATION .)
|
||||
|
||||
if (ENABLE_QT_GUI AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
install(FILES ".github/shadps4.desktop" DESTINATION "share/applications")
|
||||
install(FILES ".github/shadps4.png" DESTINATION "share/icons/hicolor/512x512/apps")
|
||||
install(FILES "dist/net.shadps4.shadPS4.desktop" DESTINATION "share/applications")
|
||||
install(FILES "dist/net.shadps4.shadPS4.metainfo.xml" DESTINATION "share/metainfo")
|
||||
install(FILES ".github/shadps4.png" DESTINATION "share/icons/hicolor/512x512/apps" RENAME "net.shadps4.shadPS4.png")
|
||||
install(FILES "src/images/net.shadps4.shadPS4.svg" DESTINATION "share/icons/hicolor/scalable/apps")
|
||||
endif()
|
||||
|
33
README.md
33
README.md
@ -55,6 +55,9 @@ This project began as a fun project. Given our limited free time, it may take so
|
||||
|
||||
# Building
|
||||
|
||||
> [!IMPORTANT]
|
||||
> If you want to use shadPS4 to play your games, you don't have to follow the build instructions, you can simply download the emulator from either the [**release tab**](https://github.com/shadps4-emu/shadPS4/releases) or the [**action tab**](https://github.com/shadps4-emu/shadPS4/actions).
|
||||
|
||||
## Windows
|
||||
|
||||
Check the build instructions for [**Windows**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-windows.md).
|
||||
@ -74,12 +77,22 @@ Check the build instructions for [**macOS**](https://github.com/shadps4-emu/shad
|
||||
|
||||
For more information on how to test, debug and report issues with the emulator or games, read the [**Debugging documentation**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/Debugging/Debugging.md).
|
||||
|
||||
# Keyboard mapping
|
||||
# Keyboard and Mouse Mappings
|
||||
|
||||
> [!NOTE]
|
||||
> Some keyboards may also require you to hold the Fn key to use the F\* keys. Mac users should use the Command key instead of Control, and need to use Command+F11 for full screen to avoid conflicting with system key bindings.
|
||||
|
||||
| Button | Function |
|
||||
|-------------|-------------|
|
||||
F10 | FPS Counter
|
||||
Ctrl+F10 | Video Debug Info
|
||||
F11 | Fullscreen
|
||||
F12 | Trigger RenderDoc Capture
|
||||
|
||||
> [!NOTE]
|
||||
> Xbox and DualShock controllers work out of the box.
|
||||
|
||||
| Controller button | Keyboard equivelant |
|
||||
| Controller button | Keyboard equivalent |
|
||||
|-------------|-------------|
|
||||
LEFT AXIS UP | W |
|
||||
LEFT AXIS DOWN | S |
|
||||
@ -89,10 +102,10 @@ RIGHT AXIS UP | I |
|
||||
RIGHT AXIS DOWN | K |
|
||||
RIGHT AXIS LEFT | J |
|
||||
RIGHT AXIS RIGHT | L |
|
||||
TRIANGLE | Numpad 8 |
|
||||
CIRCLE | Numpad 6 |
|
||||
CROSS | Numpad 2 |
|
||||
SQUARE | Numpad 4 |
|
||||
TRIANGLE | Numpad 8 or C |
|
||||
CIRCLE | Numpad 6 or B |
|
||||
CROSS | Numpad 2 or N |
|
||||
SQUARE | Numpad 4 or V |
|
||||
PAD UP | UP |
|
||||
PAD DOWN | DOWN |
|
||||
PAD LEFT | LEFT |
|
||||
@ -106,6 +119,9 @@ R2 | O |
|
||||
L3 | X |
|
||||
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.
|
||||
|
||||
|
||||
# Main team
|
||||
|
||||
- [**georgemoralis**](https://github.com/georgemoralis)
|
||||
@ -114,6 +130,11 @@ R3 | M |
|
||||
- [**skmp**](https://github.com/skmp)
|
||||
- [**wheremyfoodat**](https://github.com/wheremyfoodat)
|
||||
- [**raziel1000**](https://github.com/raziel1000)
|
||||
- [**viniciuslrangel**](https://github.com/viniciuslrangel)
|
||||
- [**roamic**](https://github.com/vladmikhalin)
|
||||
- [**poly**](https://github.com/polybiusproxy)
|
||||
- [**squidbus**](https://github.com/squidbus)
|
||||
- [**frodo**](https://github.com/baggins183)
|
||||
|
||||
Logo is done by [**Xphalnos**](https://github.com/Xphalnos)
|
||||
|
||||
|
18
REUSE.toml
18
REUSE.toml
@ -5,15 +5,21 @@ path = [
|
||||
"REUSE.toml",
|
||||
"CMakeSettings.json",
|
||||
".github/FUNDING.yml",
|
||||
".github/shadps4.desktop",
|
||||
".github/shadps4.png",
|
||||
".gitmodules",
|
||||
"documents/changelog.txt",
|
||||
"dist/MacOSBundleInfo.plist.in",
|
||||
"dist/net.shadps4.shadPS4.desktop",
|
||||
"dist/net.shadps4.shadPS4_metadata.pot",
|
||||
"dist/net.shadps4.shadPS4.metainfo.xml",
|
||||
"documents/changelog.md",
|
||||
"documents/Quickstart/2.png",
|
||||
"documents/Screenshots/*",
|
||||
"documents/Screenshots/Linux/*",
|
||||
"externals/MoltenVK/MoltenVK_icd.json",
|
||||
"scripts/ps4_names.txt",
|
||||
"src/images/about_icon.png",
|
||||
"src/images/controller_icon.png",
|
||||
"src/images/discord.png",
|
||||
"src/images/dump_icon.png",
|
||||
"src/images/exit_icon.png",
|
||||
"src/images/file_icon.png",
|
||||
@ -24,8 +30,10 @@ path = [
|
||||
"src/images/flag_us.png",
|
||||
"src/images/flag_world.png",
|
||||
"src/images/folder_icon.png",
|
||||
"src/images/github.png",
|
||||
"src/images/grid_icon.png",
|
||||
"src/images/iconsize_icon.png",
|
||||
"src/images/ko-fi.png",
|
||||
"src/images/list_icon.png",
|
||||
"src/images/list_mode_icon.png",
|
||||
"src/images/pause_icon.png",
|
||||
@ -33,10 +41,14 @@ path = [
|
||||
"src/images/refresh_icon.png",
|
||||
"src/images/settings_icon.png",
|
||||
"src/images/stop_icon.png",
|
||||
"src/images/utils_icon.png",
|
||||
"src/images/shadPS4.icns",
|
||||
"src/images/shadps4.ico",
|
||||
"src/images/net.shadps4.shadPS4.svg",
|
||||
"src/images/themes_icon.png",
|
||||
"src/images/update_icon.png",
|
||||
"src/images/youtube.png",
|
||||
"src/images/website.png",
|
||||
"src/shadps4.qrc",
|
||||
"src/shadps4.rc",
|
||||
]
|
||||
@ -57,7 +69,7 @@ SPDX-FileCopyrightText = "2019-2024 Baldur Karlsson"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
||||
[[annotations]]
|
||||
path = "externals/stb_image.h"
|
||||
path = "externals/stb/**"
|
||||
precedence = "aggregate"
|
||||
SPDX-FileCopyrightText = "2017 Sean Barrett"
|
||||
SPDX-License-Identifier = "MIT"
|
||||
|
19
cmake/Findstb.cmake
Normal file
19
cmake/Findstb.cmake
Normal file
@ -0,0 +1,19 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_path(stb_image_INCLUDE_DIR stb_image.h PATH_SUFFIXES stb)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(stb
|
||||
REQUIRED_VARS stb_image_INCLUDE_DIR
|
||||
)
|
||||
|
||||
if (stb_FOUND AND NOT TARGET stb::headers)
|
||||
add_library(stb::headers INTERFACE IMPORTED)
|
||||
set_property(TARGET stb::headers PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${stb_image_INCLUDE_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(stb_image_INCLUDE_DIR)
|
@ -1,15 +0,0 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(ZLIB_NG QUIET IMPORTED_TARGET zlib-ng)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(zlib-ng
|
||||
REQUIRED_VARS ZLIB_NG_LINK_LIBRARIES
|
||||
VERSION_VAR ZLIB_NG_VERSION
|
||||
)
|
||||
|
||||
if (zlib-ng_FOUND AND NOT TARGET zlib-ng::zlib)
|
||||
add_library(zlib-ng::zlib ALIAS PkgConfig::ZLIB_NG)
|
||||
endif()
|
46
dist/MacOSBundleInfo.plist.in
vendored
Normal file
46
dist/MacOSBundleInfo.plist.in
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
|
||||
<key>CFBundleName</key>
|
||||
<string>shadps4</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.shadps4-emu.shadps4</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>shadps4</string>
|
||||
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0.0</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.games</string>
|
||||
<key>GCSupportsGameMode</key>
|
||||
<true/>
|
||||
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
|
||||
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -1,9 +1,9 @@
|
||||
[Desktop Entry]
|
||||
Name=Shadps4
|
||||
Name=shadPS4
|
||||
Exec=shadps4
|
||||
Terminal=false
|
||||
Type=Application
|
||||
Icon=shadps4
|
||||
Comment=shadps4 emulator
|
||||
Icon=net.shadps4.shadPS4
|
||||
Comment=PlayStation 4 emulator
|
||||
Categories=Game;
|
||||
StartupWMClass=shadps4;
|
87
dist/net.shadps4.shadPS4.metainfo.xml
vendored
Normal file
87
dist/net.shadps4.shadPS4.metainfo.xml
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id translate="no">net.shadps4.shadPS4</id>
|
||||
<name translate="no">shadPS4</name>
|
||||
<developer id="net.shadps4.shadPS4">
|
||||
<name>shadPS4 Contributors</name>
|
||||
<url translate="no">https://github.com/shadps4-emu/shadps4/graphs/contributors</url>
|
||||
</developer>
|
||||
<summary>PS4 Emulator</summary>
|
||||
<metadata_license translate="no">CC0-1.0</metadata_license>
|
||||
<project_license translate="no">GPL-2.0</project_license>
|
||||
<launchable type="desktop-id" translate="no">net.shadps4.shadPS4.desktop</launchable>
|
||||
<url type="homepage" translate="no">https://shadps4.net/</url>
|
||||
<description>
|
||||
<p>shadPS4 is an early PlayStation 4 emulator for Windows, Linux and macOS written in C++.</p>
|
||||
<p>The emulator is still early in development, so don't expect a flawless experience. Nonetheless, the emulator can already run a number of commercial games.</p>
|
||||
</description>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image type="source" translate="no" >https://cdn.jsdelivr.net/gh/shadps4-emu/shadps4@main/documents/Screenshots/1.png</image>
|
||||
<caption>Bloodborne</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source" translate="no">https://cdn.jsdelivr.net/gh/shadps4-emu/shadps4@main/documents/Screenshots/2.png</image>
|
||||
<caption>Hatsune Miku: Project DIVA Future Tone</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source" translate="no">https://cdn.jsdelivr.net/gh/shadps4-emu/shadps4@main/documents/Screenshots/3.png</image>
|
||||
<caption>Yakuza 0</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source" translate="no">https://cdn.jsdelivr.net/gh/shadps4-emu/shadps4@main/documents/Screenshots/4.png</image>
|
||||
<caption>Persona 4 Golden</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<categories>
|
||||
<category translate="no">Game</category>
|
||||
</categories>
|
||||
<releases>
|
||||
<release version="0.6.0" date="2025-01-31">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.6.0</url>
|
||||
</release>
|
||||
<release version="0.5.0" date="2024-12-25">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.5.0</url>
|
||||
</release>
|
||||
<release version="0.4.0" date="2024-10-31">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.4.0</url>
|
||||
</release>
|
||||
<release version="0.3.0" date="2024-09-23">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.3.0</url>
|
||||
</release>
|
||||
<release version="0.2.0" date="2024-08-15">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v.0.2.0</url>
|
||||
</release>
|
||||
<release version="0.1.0" date="2024-07-01">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/0.1.0</url>
|
||||
</release>
|
||||
<release version="0.0.3" date="2024-03-23">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.3</url>
|
||||
</release>
|
||||
<release version="0.0.2" date="2023-10-21">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.2</url>
|
||||
</release>
|
||||
<release version="0.0.1" date="2024-09-29">
|
||||
<url>https://github.com/shadps4-emu/shadPS4/releases/tag/v0.0.1</url>
|
||||
</release>
|
||||
</releases>
|
||||
<content_rating type="oars-1.1"/>
|
||||
<supports>
|
||||
<control translate="no">keyboard</control>
|
||||
</supports>
|
||||
<recommends>
|
||||
<control translate="no">gamepad</control>
|
||||
</recommends>
|
||||
<requires>
|
||||
<internet translate="no">offline-only</internet>
|
||||
</requires>
|
||||
<provides>
|
||||
<binary translate="no">shadps4</binary>
|
||||
</provides>
|
||||
<keywords>
|
||||
<keyword>emulator</keyword>
|
||||
<keyword>emulation</keyword>
|
||||
<keyword translate="no">playstation</keyword>
|
||||
<keyword translate="no">ps4</keyword>
|
||||
</keywords>
|
||||
</component>
|
65
dist/net.shadps4.shadPS4_metadata.pot
vendored
Normal file
65
dist/net.shadps4.shadPS4_metadata.pot
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2024-11-08 09:07+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#. (itstool) path: component/name
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:4
|
||||
msgid "shadPS4"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: developer/name
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:6
|
||||
msgid "shadPS4 Contributors"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: component/summary
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:9
|
||||
msgid "PS4 Emulator"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: description/p
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:16
|
||||
msgid "shadPS4 is an early PlayStation 4 emulator for Windows, Linux and macOS written in C++."
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: description/p
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:17
|
||||
msgid "The emulator is still early in development, so don't expect a flawless experience. Nonetheless, the emulator can already run a number of commercial games."
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: screenshot/caption
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:22
|
||||
msgid "Bloodborne"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: screenshot/caption
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:26
|
||||
msgid "Hatsune Miku: Project DIVA Future Tone"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: screenshot/caption
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:30
|
||||
msgid "Yakuza Kiwami"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: screenshot/caption
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:34
|
||||
msgid "Persona 4 Golden"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: keywords/keyword
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:59
|
||||
msgid "emulator"
|
||||
msgstr ""
|
||||
|
||||
#. (itstool) path: keywords/keyword
|
||||
#: ./net.shadps4.shadPS4.metainfo.xml:60
|
||||
msgid "emulation"
|
||||
msgstr ""
|
@ -22,7 +22,10 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
- A processor with at least 4 cores and 6 threads
|
||||
- Above 2.5 GHz frequency
|
||||
- required support AVX2 extension or Rosetta 2 on ARM
|
||||
- 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
|
||||
- **AMD**: Jaguar generation or newer
|
||||
- **Apple**: Rosetta 2 on macOS 15 or newer
|
||||
|
||||
### GPU
|
||||
|
||||
|
BIN
documents/Screenshots/Linux/1.png
Normal file
BIN
documents/Screenshots/Linux/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
documents/Screenshots/Linux/2.png
Normal file
BIN
documents/Screenshots/Linux/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
documents/Screenshots/Linux/3.png
Normal file
BIN
documents/Screenshots/Linux/3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
BIN
documents/Screenshots/Linux/4.png
Normal file
BIN
documents/Screenshots/Linux/4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
documents/Screenshots/Linux/5.png
Normal file
BIN
documents/Screenshots/Linux/5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
@ -3,59 +3,134 @@ SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
-->
|
||||
|
||||
## Build shadPS4 for Linux
|
||||
## Build shadPS4 for Linux
|
||||
|
||||
### Install the necessary tools to build shadPS4:
|
||||
First and foremost, Clang 18 is the **recommended compiler** as it is used for official builds and CI. If you build with GCC, you might encounter issues — please report any you find. Additionally, if you choose to use GCC, please build shadPS4 with Clang at least once before creating an `[APP BUG]` issue or submitting a pull request.
|
||||
|
||||
## Preparatory steps
|
||||
|
||||
### Installing dependencies
|
||||
|
||||
#### Debian & Ubuntu
|
||||
|
||||
```
|
||||
sudo apt install build-essential clang git cmake libasound2-dev libpulse-dev libopenal-dev libssl-dev zlib1g-dev libedit-dev libudev-dev libevdev-dev libsdl2-dev libjack-dev libsndio-dev qt6-base-dev qt6-tools-dev qt6-multimedia-dev libvulkan-dev vulkan-validationlayers
|
||||
```
|
||||
|
||||
#### Fedora
|
||||
|
||||
```
|
||||
sudo dnf install clang git cmake libatomic alsa-lib-devel pipewire-jack-audio-connection-kit-devel openal-devel openssl-devel libevdev-devel libudev-devel libXext-devel qt6-qtbase-devel qt6-qtbase-private-devel qt6-qtmultimedia-devel qt6-qtsvg-devel qt6-qttools-devel vulkan-devel vulkan-validation-layers
|
||||
```
|
||||
|
||||
#### Arch Linux
|
||||
|
||||
```
|
||||
sudo pacman -S base-devel clang git cmake sndio jack2 openal qt6-base qt6-declarative qt6-multimedia sdl2 vulkan-validation-layers
|
||||
```
|
||||
|
||||
**Note**: The `shadps4-git` AUR package is not maintained by any of the developers, and it uses the default compiler, which is often set to GCC. Use at your own discretion.
|
||||
|
||||
#### OpenSUSE
|
||||
|
||||
```
|
||||
sudo zypper install clang git cmake libasound2 libpulse-devel libsndio7 libjack-devel openal-soft-devel libopenssl-devel zlib-devel libedit-devel systemd-devel libevdev-devel qt6-base-devel qt6-multimedia-devel qt6-svg-devel qt6-linguist-devel qt6-gui-private-devel vulkan-devel vulkan-validationlayers
|
||||
```
|
||||
### Cloning and compiling:
|
||||
|
||||
Clone the repository recursively:
|
||||
#### Other Linux distributions
|
||||
|
||||
You can try one of two methods:
|
||||
|
||||
- Search the packages by name and install them with your package manager, or
|
||||
- Install [distrobox](https://distrobox.it/), create a container using any of the distributions cited above as a base, for Arch Linux you'd do:
|
||||
|
||||
```
|
||||
distrobox create --name archlinux --init --image archlinux:latest
|
||||
```
|
||||
|
||||
and install the dependencies on that container as cited above.
|
||||
This option is **highly recommended** for NixOS and distributions with immutable/atomic filesystems (example: Fedora Kinoite, SteamOS).
|
||||
|
||||
### Cloning
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/shadps4-emu/shadPS4.git
|
||||
cd shadPS4
|
||||
```
|
||||
|
||||
Generate the build directory in the shadPS4 directory. To disable the QT GUI, remove the ```-DENABLE_QT_GUI=ON``` flag:
|
||||
## Building
|
||||
|
||||
There are 3 options you can choose from. Option 1 is **highly recommended**.
|
||||
|
||||
#### Option 1: Terminal-only
|
||||
|
||||
1. Generate the build directory in the shadPS4 directory.
|
||||
|
||||
**Note**: Clang is the compiler used for official builds and CI. If you build with GCC, you might encounter issues—please report any you find. If you choose to use GCC, we recommend building with Clang at least once before submitting a pull request.
|
||||
```
|
||||
cmake -S . -B build/ -DENABLE_QT_GUI=ON -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++
|
||||
```
|
||||
|
||||
Enter the directory:
|
||||
To disable the Qt GUI, remove the `-DENABLE_QT_GUI=ON` flag. To change the build type (for debugging), add `-DCMAKE_BUILD_TYPE=Debug`.
|
||||
|
||||
2. Use CMake to build the project:
|
||||
|
||||
```
|
||||
cd build/
|
||||
cmake --build ./build --parallel$(nproc)
|
||||
```
|
||||
|
||||
Use make to build the project:
|
||||
If your computer freezes during this step, this could be caused by excessive system resource usage. In that case, remove `--parallel$(nproc)`.
|
||||
|
||||
Now run the emulator. If Qt was enabled at configure time:
|
||||
|
||||
```
|
||||
cmake --build . --parallel$(nproc)
|
||||
./build/shadps4
|
||||
```
|
||||
|
||||
Now run the emulator. If QT is enabled:
|
||||
```
|
||||
./shadps4
|
||||
```
|
||||
Otherwise, specify the path to your PKG's boot file:
|
||||
|
||||
```
|
||||
./shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
|
||||
./build/shadps4 /"PATH"/"TO"/"GAME"/"FOLDER"/eboot.bin
|
||||
```
|
||||
|
||||
You can also specify the Game ID as an argument for which game to boot, as long as the folder containing the games is specified in config.toml (example: Bloodborne (US) is CUSA00900).
|
||||
#### Option 2: Configuring with cmake-gui
|
||||
|
||||
`cmake-gui` should be installed by default alongside `cmake`, if not search for the package in your package manager and install it.
|
||||
|
||||
Open `cmake-gui` and specify the source code and build directories. If you cloned the source code to your Home directory, it would be `/home/user/shadPS4` and `/home/user/shadPS4/build`.
|
||||
|
||||
Click on Configure, select "Unix Makefiles", select "Specify native compilers", click Next and choose `clang` and `clang++` as the C and CXX compilers. Usually they are located in `/bin/clang` and `/bin/clang++`. Click on Finish and let it configure the project.
|
||||
|
||||
Now every option should be displayed in red. Change anything you want, then click on Generate to make the changes permanent, then open a terminal window and do step 2 of Option 1.
|
||||
|
||||
#### Option 3: Visual Studio Code
|
||||
|
||||
This option is pretty convoluted and should only be used if you have VSCode as your default IDE, or just prefer building and debugging projects through it. This also assumes that you're using an Arch Linux environment, as the naming for some options might differ from other distros.
|
||||
|
||||
[Download Visual Studio Code for your platform](https://code.visualstudio.com/download), or use [Code - OSS](https://github.com/microsoft/vscode) if you'd like. Code - OSS is available on most Linux distributions' package repositories (on Arch Linux it is simply named `code`).
|
||||
|
||||
Once set up, go to Extensions and install "CMake Tools":
|
||||
|
||||

|
||||
|
||||
You can also install other CMake and Clang related extensions if you'd like, but this one is what enables you to configure and build CMake projects directly within VSCode.
|
||||
|
||||
Go to Settings, filter by `@ext:ms-vscode.cmake-tools configure` and disable this option:
|
||||
|
||||

|
||||
|
||||
If you wish to build with the Qt GUI, add `-DENABLE_QT_GUI=ON` to the configure arguments:
|
||||
|
||||

|
||||
|
||||
On the CMake tab, change the options as you wish, but make sure that it looks similar to or exactly like this:
|
||||
|
||||

|
||||
|
||||
When hovering over Project Status > Configure, there should be an icon titled "Configure". Click on it and let it configure the project, then do the same for Project Status > Build.
|
||||
|
||||
If you want to debug it, change the build type under Project Status > Configure to Debug (it should be the default) and compile it, then click on the icon in Project Status > Debug. If you simply want to launch the shadPS4 executable from within VSCode, click on the icon in Project Status > Launch.
|
||||
|
||||
Don't forget to change the launch target for both options to the shadPS4 executable inside shadPS4/build:
|
||||
|
||||

|
||||
|
@ -24,23 +24,21 @@ eval $(/opt/homebrew/bin/brew shellenv)
|
||||
brew install clang-format cmake
|
||||
```
|
||||
|
||||
Next, install x86_64 Homebrew and libraries.
|
||||
Next, install x86_64 Qt. You can skip these steps and move on to **Cloning and compiling** if you do not intend to build the Qt GUI.
|
||||
|
||||
**If you are on an ARM Mac:**
|
||||
```
|
||||
# Installs x86_64 Homebrew to /usr/local
|
||||
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
# Installs libraries.
|
||||
arch -x86_64 /usr/local/bin/brew install molten-vk qt@6
|
||||
arch -x86_64 /usr/local/bin/brew install qt@6
|
||||
```
|
||||
|
||||
**If you are on an x86_64 Mac:**
|
||||
```
|
||||
brew install molten-vk qt@6
|
||||
brew install qt@6
|
||||
```
|
||||
|
||||
If you don't need the Qt GUI you can remove `qt@6` from the last command.
|
||||
|
||||
### Cloning and compiling:
|
||||
|
||||
Clone the repository recursively:
|
||||
|
@ -25,8 +25,8 @@ Once you are within the installer:
|
||||
|
||||
Beware, this requires you to create a Qt account. If you do not want to do this, please follow the MSYS2/MinGW compilation method instead.
|
||||
|
||||
1. Under the current, non beta version of Qt (at the time of writing 6.7.2), select the option `MSVC 2019 64-bit` or similar.
|
||||
If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2019 ARM64` instead.
|
||||
1. Under the current, non beta version of Qt (at the time of writing 6.7.3), select the option `MSVC 2022 64-bit` or similar, as well as `QT Multimedia`.
|
||||
If you are on Windows on ARM / Qualcomm Snapdragon Elite X, select `MSVC 2022 ARM64` instead.
|
||||
|
||||
Go through the installation normally. If you know what you are doing, you may unselect individual components that eat up too much disk space.
|
||||
|
||||
@ -35,7 +35,7 @@ Beware, this requires you to create a Qt account. If you do not want to do this,
|
||||
Once you are finished, you will have to configure Qt within Visual Studio:
|
||||
|
||||
1. Tools -> Options -> Qt -> Versions
|
||||
2. Add a new Qt version and navigate it to the correct folder. Should look like so: `C:\Qt\6.7.2\msvc2019_64`
|
||||
2. Add a new Qt version and navigate it to the correct folder. Should look like so: `C:\Qt\6.7.3\msvc2022_64`
|
||||
3. Enable the default checkmark on the new version you just created.
|
||||
|
||||
### (Prerequisite) Download [**Git for Windows**](https://git-scm.com/download/win)
|
||||
@ -55,16 +55,16 @@ Go through the Git for Windows installation as normal
|
||||
3. If you want to build shadPS4 with the Qt Gui:
|
||||
1. Click x64-Clang-Release and select "Manage Configurations"
|
||||
2. Look for "CMake command arguments" and add to the text field
|
||||
`-DENABLE_QT_GUI=ON -DCMAKE_PREFIX_PATH=C:\Qt\6.7.2\msvc2019_64`
|
||||
`-DENABLE_QT_GUI=ON -DCMAKE_PREFIX_PATH=C:\Qt\6.7.3\msvc2022_64`
|
||||
(Change Qt path if you've installed it to non-default path)
|
||||
3. Press CTRL+S to save and wait a moment for CMake generation
|
||||
4. Change the project to build to shadps4.exe
|
||||
5. Build -> Build All
|
||||
|
||||
Your shadps4.exe will be in `c:\path\to\source\Build\x64-Clang-Release\`
|
||||
Your shadps4.exe will be in `C:\path\to\source\Build\x64-Clang-Release\`
|
||||
|
||||
To automatically populate the necessary files to run shadPS4.exe, run in a command prompt or terminal:
|
||||
`C:\Qt\6.7.2\msvc2019_64\bin\windeployqt.exe "c:\path\to\shadps4.exe"`
|
||||
`C:\Qt\6.7.3\msvc2022_64\bin\windeployqt6.exe "C:\path\to\shadps4.exe"`
|
||||
(Change Qt path if you've installed it to non-default path)
|
||||
|
||||
## Option 2: MSYS2/MinGW
|
||||
@ -79,7 +79,7 @@ Normal x86-based computers, follow:
|
||||
|
||||
1. Open "MSYS2 MINGW64" from your new applications
|
||||
2. Run `pacman -Syu`, let it complete;
|
||||
3. Run `pacman -S --needed git mingw-w64-x86_64-binutils mingw-w64-x86_64-clang mingw-w64-x86_64-cmake mingw-w64-x86_64-ninja mingw-w64-x86_64-ffmpeg`
|
||||
3. Run `pacman -S --needed git mingw-w64-x86_64-binutils mingw-w64-x86_64-clang mingw-w64-x86_64-cmake mingw-w64-x86_64-rapidjson mingw-w64-x86_64-ninja mingw-w64-x86_64-ffmpeg`
|
||||
1. Optional (Qt only): run `pacman -S --needed mingw-w64-x86_64-qt6-base mingw-w64-x86_64-qt6-tools mingw-w64-x86_64-qt6-multimedia`
|
||||
4. Run `git clone --depth 1 --recursive https://github.com/shadps4-emu/shadPS4`
|
||||
5. Run `cd shadPS4`
|
||||
@ -93,7 +93,7 @@ ARM64-based computers, follow:
|
||||
|
||||
1. Open "MSYS2 CLANGARM64" from your new applications
|
||||
2. Run `pacman -Syu`, let it complete;
|
||||
3. Run `pacman -S --needed git mingw-w64-clang-aarch64-binutils mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-ninja mingw-w64-clang-aarch64-ffmpeg`
|
||||
3. Run `pacman -S --needed git mingw-w64-clang-aarch64-binutils mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-rapidjson mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-ninja mingw-w64-clang-aarch64-ffmpeg`
|
||||
1. Optional (Qt only): run `pacman -S --needed mingw-w64-clang-aarch64-qt6-base mingw-w64-clang-aarch64-qt6-tools mingw-w64-clang-aarch64-qt6-multimedia`
|
||||
4. Run `git clone --depth 1 --recursive https://github.com/shadps4-emu/shadPS4`
|
||||
5. Run `cd shadPS4`
|
||||
|
@ -1,3 +1,47 @@
|
||||
v0.4.0 31/10/2024 - codename divicius
|
||||
=================
|
||||
|
||||
- Shader recompiler fixes
|
||||
- Emulated support for cpus that doesn't have SSE4.2a (intel cpus)
|
||||
- Frame graph + Precise 60 fps timing
|
||||
- Save data: fix nullptr & concurrent file write
|
||||
- Auto Update
|
||||
- Error dialog implementation
|
||||
- Swapchain recreation and window resizing
|
||||
- Add playback of background/title music in game list
|
||||
- Kernel: Quiet sceKernelWaitEventFlag error log on timeout
|
||||
- Improve keyboard navigation in game list
|
||||
- core/memory: Pooled memory implementation
|
||||
- Fix PKG loading
|
||||
- replace trophy xml assert with error
|
||||
- Refactor audio handling with range checks, buffer threshold, and lock
|
||||
- audio_core: Fix return value types and shift some error handling to library
|
||||
- Devtools: PM4 Explorer
|
||||
- Initial support of Geometry shaders
|
||||
- Working touchpad support
|
||||
- net: Stub sceNetErrnoLoc
|
||||
- Add support to click touchpad using back button on non PS4/5 controllers
|
||||
- Multiple Install Folders
|
||||
- Using a more standard data directory for linux
|
||||
- video_core: Implement sceGnmInsertPushColorMarker
|
||||
- ime_dialog: Initial implementation
|
||||
- Network libs fixes
|
||||
- Use GetSystemTimePreciseAsFileTime to fix fps timing issues
|
||||
- Added adaptive mutex initializer
|
||||
- Small Np + trophy fixes
|
||||
- Separate Updates from Game Folder
|
||||
- Minor Fixes for Separate Update Folder
|
||||
- AvPlayer: Do not align w/h to 16 with vdec2
|
||||
- Improve sceSystemServiceReceiveEvent stub
|
||||
- renderer_vulkan: Commize and adjust buffer bindings
|
||||
- Add poll interval to libScePad
|
||||
- Add more surface format mappings.
|
||||
- vulkan: Report only missing format feature flags.
|
||||
- IME implementation
|
||||
- Videodec2 implementation
|
||||
- path_util: Make sure macOS has current directory set and clean up path code.
|
||||
- Load LLE modules from sys_modules/GAMEID folder
|
||||
|
||||
v0.3.0 23/09/2024 - codename broamic
|
||||
=================
|
||||
|
19
documents/patching-shader.md
Normal file
19
documents/patching-shader.md
Normal file
@ -0,0 +1,19 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2024 shadPS4 Emulator Project
|
||||
SPDX-License-Identifier: GPL-2.0-or-later
|
||||
-->
|
||||
|
||||
### Install Vulkan SDK and \*ensure `spirv-cross` and `glslc` are in PATH\*.
|
||||
|
||||
1. Enable `dumpShaders` in config.toml
|
||||
|
||||
2. Run `spirv-cross -V fs_0x000000.spv --output fs_0x000000.glsl` to decompile the SPIR-V IR to GLSL.
|
||||
|
||||
3. Edit the GLSL file as you wish
|
||||
|
||||
4. To compile back to SPIR-V, run (change the _**-fshader-stage**_ to correct stage):
|
||||
`glslc --target-env=vulkan1.3 --target-spv=spv1.6 -fshader-stage=frag fs_0x000000.glsl -o fs_0x000000.spv`
|
||||
|
||||
5. Put the updated .spv file to `shader/patch` folder with the same name as the original shader
|
||||
|
||||
6. Enable `patchShaders` in config.toml
|
77
externals/CMakeLists.txt
vendored
77
externals/CMakeLists.txt
vendored
@ -8,6 +8,9 @@ set_directory_properties(PROPERTIES
|
||||
SYSTEM ON
|
||||
)
|
||||
|
||||
# Set CMP0069 policy to "NEW" in order to ensure consistent behavior when building external targets with LTO enabled
|
||||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
|
||||
|
||||
if (MSVC)
|
||||
# Silence "deprecation" warnings
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
|
||||
@ -35,10 +38,11 @@ else()
|
||||
if (NOT TARGET cryptopp::cryptopp)
|
||||
set(CRYPTOPP_INSTALL OFF)
|
||||
set(CRYPTOPP_BUILD_TESTING OFF)
|
||||
set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp/)
|
||||
set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp)
|
||||
add_subdirectory(cryptopp-cmake)
|
||||
file(COPY cryptopp DESTINATION cryptopp FILES_MATCHING PATTERN "*.h")
|
||||
target_include_directories(cryptopp INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/cryptopp")
|
||||
# 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()
|
||||
endif()
|
||||
|
||||
@ -52,14 +56,23 @@ file(GLOB LIBATRAC9_SOURCES LibAtrac9/C/src/*.c)
|
||||
add_library(LibAtrac9 STATIC ${LIBATRAC9_SOURCES})
|
||||
target_include_directories(LibAtrac9 INTERFACE LibAtrac9/C/src)
|
||||
|
||||
# Zlib-Ng
|
||||
if (NOT TARGET zlib-ng::zlib)
|
||||
# zlib
|
||||
if (NOT TARGET ZLIB::ZLIB)
|
||||
set(ZLIB_ENABLE_TESTS OFF)
|
||||
set(WITH_GTEST OFF)
|
||||
set(WITH_NEW_STRATEGIES ON)
|
||||
set(WITH_NATIVE_INSTRUCTIONS ON)
|
||||
add_subdirectory(zlib-ng)
|
||||
add_library(zlib-ng::zlib ALIAS zlib)
|
||||
set(ZLIB_COMPAT ON CACHE BOOL "" FORCE)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
ZLIB
|
||||
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zlib-ng"
|
||||
OVERRIDE_FIND_PACKAGE
|
||||
)
|
||||
FetchContent_MakeAvailable(ZLIB)
|
||||
add_library(ZLIB::ZLIB ALIAS zlib)
|
||||
# libpng expects this variable to exist after its find_package(ZLIB)
|
||||
set(ZLIB_INCLUDE_DIRS "${FETCHCONTENT_BASE_DIR}/zlib-build")
|
||||
endif()
|
||||
|
||||
# SDL3
|
||||
@ -97,7 +110,7 @@ if (NOT TARGET glslang::glslang)
|
||||
set(ENABLE_OPT OFF CACHE BOOL "")
|
||||
add_subdirectory(glslang)
|
||||
file(COPY glslang/SPIRV DESTINATION glslang/glslang FILES_MATCHING PATTERN "*.h")
|
||||
target_include_directories(SPIRV INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/glslang")
|
||||
target_include_directories(glslang INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/glslang")
|
||||
endif()
|
||||
|
||||
# Robin-map
|
||||
@ -153,13 +166,15 @@ if (NOT TARGET half::half)
|
||||
add_library(half::half ALIAS half)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# date
|
||||
if (NOT TARGET date::date-tz)
|
||||
option(BUILD_TZ_LIB "" ON)
|
||||
option(USE_SYSTEM_TZ_DB "" ON)
|
||||
add_subdirectory(date)
|
||||
endif()
|
||||
# libpng
|
||||
if (NOT TARGET PNG::PNG)
|
||||
set(PNG_SHARED OFF CACHE BOOL "" FORCE)
|
||||
set(PNG_STATIC ON CACHE BOOL "" FORCE)
|
||||
set(PNG_TESTS OFF CACHE BOOL "" FORCE)
|
||||
set(PNG_TOOLS OFF CACHE BOOL "" FORCE)
|
||||
set(SKIP_INSTALL_ALL OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(libpng)
|
||||
add_library(PNG::PNG ALIAS png_static)
|
||||
endif()
|
||||
|
||||
# Dear ImGui
|
||||
@ -174,11 +189,15 @@ add_library(Dear_ImGui
|
||||
target_include_directories(Dear_ImGui INTERFACE dear_imgui/)
|
||||
|
||||
# Tracy
|
||||
option(TRACY_ENABLE "" ON)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
option(TRACY_ENABLE "" OFF)
|
||||
else()
|
||||
option(TRACY_ENABLE "" ON)
|
||||
endif()
|
||||
option(TRACY_NO_CRASH_HANDLER "" ON) # Otherwise texture cache exceptions will be treaten as a crash
|
||||
option(TRACY_ON_DEMAND "" ON)
|
||||
option(TRACY_NO_FRAME_IMAGE "" ON)
|
||||
option(TRACY_FIBERS "" ON) # For AmdGpu frontend profiling
|
||||
option(TRACY_FIBERS "" OFF) # For AmdGpu frontend profiling, disabled due to instability
|
||||
option(TRACY_NO_SYSTEM_TRACING "" ON)
|
||||
option(TRACY_NO_CALLSTACK "" ON)
|
||||
option(TRACY_NO_CODE_TRANSFER "" ON)
|
||||
@ -194,10 +213,30 @@ endif()
|
||||
|
||||
# Discord RPC
|
||||
if (ENABLE_DISCORD_RPC)
|
||||
set(BUILD_EXAMPLES OFF)
|
||||
add_subdirectory(discord-rpc/)
|
||||
target_include_directories(discord-rpc INTERFACE discord-rpc/include)
|
||||
add_subdirectory(discord-rpc)
|
||||
endif()
|
||||
|
||||
# GCN Headers
|
||||
add_subdirectory(gcn)
|
||||
|
||||
# stb
|
||||
if (NOT TARGET stb::headers)
|
||||
add_library(stb INTERFACE)
|
||||
target_include_directories(stb INTERFACE stb)
|
||||
add_library(stb::headers ALIAS stb)
|
||||
endif()
|
||||
|
||||
# Apple-only dependencies
|
||||
if (APPLE)
|
||||
# date
|
||||
if (NOT TARGET date::date-tz)
|
||||
option(BUILD_TZ_LIB "" ON)
|
||||
option(USE_SYSTEM_TZ_DB "" ON)
|
||||
add_subdirectory(date)
|
||||
endif()
|
||||
|
||||
# MoltenVK
|
||||
if (NOT TARGET MoltenVK)
|
||||
add_subdirectory(MoltenVK)
|
||||
endif()
|
||||
endif()
|
||||
|
2
externals/LibAtrac9
vendored
2
externals/LibAtrac9
vendored
@ -1 +1 @@
|
||||
Subproject commit 82767fe38823c32536726ea798f392b0b49e66b9
|
||||
Subproject commit 9640129dc6f2afbca6ceeca3019856e8653a5fb2
|
93
externals/MoltenVK/CMakeLists.txt
vendored
Normal file
93
externals/MoltenVK/CMakeLists.txt
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
# Prepare MoltenVK Git revision
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
OUTPUT_VARIABLE MVK_GIT_REV
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
endif()
|
||||
set(MVK_GENERATED_INCLUDES ${CMAKE_CURRENT_BINARY_DIR}/Generated)
|
||||
file(WRITE ${MVK_GENERATED_INCLUDES}/mvkGitRevDerived.h "static const char* mvkRevString = \"${MVK_GIT_REV}\";")
|
||||
message(STATUS "MoltenVK revision: ${MVK_GIT_REV}")
|
||||
|
||||
# Prepare MoltenVK version
|
||||
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK/MoltenVK/API/mvk_private_api.h MVK_PRIVATE_API)
|
||||
string(REGEX MATCH "#define MVK_VERSION_MAJOR [0-9]+" MVK_VERSION_MAJOR_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_MAJOR "${MVK_VERSION_MAJOR_LINE}")
|
||||
string(REGEX MATCH "#define MVK_VERSION_MINOR [0-9]+" MVK_VERSION_MINOR_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_MINOR "${MVK_VERSION_MINOR_LINE}")
|
||||
string(REGEX MATCH "#define MVK_VERSION_PATCH [0-9]+" MVK_VERSION_PATCH_LINE "${MVK_PRIVATE_API}")
|
||||
string(REGEX MATCH "[0-9]+" MVK_VERSION_PATCH "${MVK_VERSION_PATCH_LINE}")
|
||||
set(MVK_VERSION "${MVK_VERSION_MAJOR}.${MVK_VERSION_MINOR}.${MVK_VERSION_PATCH}")
|
||||
message(STATUS "MoltenVK version: ${MVK_VERSION}")
|
||||
|
||||
# Find required system libraries
|
||||
find_library(APPKIT_LIBRARY AppKit REQUIRED)
|
||||
find_library(FOUNDATION_LIBRARY Foundation REQUIRED)
|
||||
find_library(IOKIT_LIBRARY IOKit REQUIRED)
|
||||
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
||||
find_library(METAL_LIBRARY Metal REQUIRED)
|
||||
find_library(QUARTZCORE_LIBRARY QuartzCore REQUIRED)
|
||||
|
||||
# cereal
|
||||
option(SKIP_PORTABILITY_TEST "" ON)
|
||||
option(BUILD_DOC "" OFF)
|
||||
option(BUILD_SANDBOX "" OFF)
|
||||
option(SKIP_PERFORMANCE_COMPARISON "" ON)
|
||||
option(SPIRV_CROSS_SKIP_INSTALL "" ON)
|
||||
add_subdirectory(cereal)
|
||||
|
||||
# SPIRV-Cross
|
||||
option(SPIRV_CROSS_CLI "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_TESTS "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_HLSL "" OFF)
|
||||
option(SPIRV_CROSS_ENABLE_CPP "" OFF)
|
||||
option(SPIRV_CROSS_SKIP_INSTALL "" ON)
|
||||
add_subdirectory(SPIRV-Cross)
|
||||
|
||||
# Common
|
||||
set(MVK_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/Common)
|
||||
file(GLOB_RECURSE MVK_COMMON_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_COMMON_DIR}/*.cpp
|
||||
${MVK_COMMON_DIR}/*.m
|
||||
${MVK_COMMON_DIR}/*.mm)
|
||||
set(MVK_COMMON_INCLUDES ${MVK_COMMON_DIR})
|
||||
|
||||
add_library(MoltenVKCommon STATIC ${MVK_COMMON_SOURCES})
|
||||
target_include_directories(MoltenVKCommon PUBLIC ${MVK_COMMON_INCLUDES})
|
||||
target_compile_options(MoltenVKCommon PRIVATE -w)
|
||||
|
||||
# MoltenVKShaderConverter
|
||||
set(MVK_SHADER_CONVERTER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVKShaderConverter)
|
||||
file(GLOB_RECURSE MVK_SHADER_CONVERTER_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.cpp
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.m
|
||||
${MVK_SHADER_CONVERTER_DIR}/MoltenVKShaderConverter/*.mm)
|
||||
set(MVK_SHADER_CONVERTER_INCLUDES ${MVK_SHADER_CONVERTER_DIR} ${MVK_SHADER_CONVERTER_DIR}/include)
|
||||
|
||||
add_library(MoltenVKShaderConverter STATIC ${MVK_SHADER_CONVERTER_SOURCES})
|
||||
target_include_directories(MoltenVKShaderConverter PUBLIC ${MVK_SHADER_CONVERTER_INCLUDES})
|
||||
target_compile_options(MoltenVKShaderConverter PRIVATE -w)
|
||||
target_link_libraries(MoltenVKShaderConverter PRIVATE spirv-cross-msl spirv-cross-reflect MoltenVKCommon)
|
||||
target_compile_definitions(MoltenVKShaderConverter PRIVATE MVK_EXCLUDE_SPIRV_TOOLS=1)
|
||||
|
||||
# MoltenVK
|
||||
set(MVK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/MoltenVK/MoltenVK)
|
||||
file(GLOB_RECURSE MVK_SOURCES CONFIGURE_DEPENDS
|
||||
${MVK_DIR}/MoltenVK/*.cpp
|
||||
${MVK_DIR}/MoltenVK/*.m
|
||||
${MVK_DIR}/MoltenVK/*.mm)
|
||||
file(GLOB MVK_SRC_INCLUDES LIST_DIRECTORIES ON ${MVK_DIR}/MoltenVK/*)
|
||||
set(MVK_INCLUDES ${MVK_SRC_INCLUDES} ${MVK_GENERATED_INCLUDES} ${MVK_DIR}/include)
|
||||
|
||||
add_library(MoltenVK SHARED ${MVK_SOURCES})
|
||||
target_include_directories(MoltenVK PRIVATE ${MVK_INCLUDES})
|
||||
target_compile_options(MoltenVK PRIVATE -w)
|
||||
target_link_libraries(MoltenVK PRIVATE
|
||||
${APPKIT_LIBRARY} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${IOSURFACE_LIBRARY} ${METAL_LIBRARY} ${QUARTZCORE_LIBRARY}
|
||||
Vulkan::Headers cereal::cereal spirv-cross-msl MoltenVKCommon MoltenVKShaderConverter)
|
||||
target_compile_definitions(MoltenVK PRIVATE MVK_FRAMEWORK_VERSION=${MVK_VERSION} MVK_USE_METAL_PRIVATE_API=1)
|
1
externals/MoltenVK/MoltenVK
vendored
Submodule
1
externals/MoltenVK/MoltenVK
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 0c090001cb42997031cfe43914340e2639944972
|
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
|
||||
}
|
||||
}
|
1
externals/MoltenVK/SPIRV-Cross
vendored
Submodule
1
externals/MoltenVK/SPIRV-Cross
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 1a7b7ef6de02cf6767e42b10ddad217c45e90d47
|
1
externals/MoltenVK/cereal
vendored
Submodule
1
externals/MoltenVK/cereal
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit d1fcec807b372f04e4c1041b3058e11c12853e6e
|
2
externals/date
vendored
2
externals/date
vendored
@ -1 +1 @@
|
||||
Subproject commit dd8affc6de5755e07638bf0a14382d29549d6ee9
|
||||
Subproject commit 28b7b232521ace2c8ef3f2ad4126daec3569c14f
|
2
externals/discord-rpc
vendored
2
externals/discord-rpc
vendored
@ -1 +1 @@
|
||||
Subproject commit 4ec218155d73bcb8022f8f7ca72305d801f84beb
|
||||
Subproject commit 51b09d426a4a1bcfa6ee6d4894e57d669f4a2e65
|
2
externals/ext-boost
vendored
2
externals/ext-boost
vendored
@ -1 +1 @@
|
||||
Subproject commit f2474e1b584fb7a3ed6f85ba875e6eacd742ec8a
|
||||
Subproject commit ca6f230e67be7cc45fc919057f07b2aee64dadc1
|
2
externals/ffmpeg-core
vendored
2
externals/ffmpeg-core
vendored
@ -1 +1 @@
|
||||
Subproject commit e30b7d7fe228bfb3f6e41ce1040b44a15eb7d5e0
|
||||
Subproject commit 27de97c826b6b40c255891c37ac046a25836a575
|
2
externals/glslang
vendored
2
externals/glslang
vendored
@ -1 +1 @@
|
||||
Subproject commit e61d7bb3006f451968714e2f653412081871e1ee
|
||||
Subproject commit a0995c49ebcaca2c6d3b03efbabf74f3843decdb
|
1
externals/libpng
vendored
Submodule
1
externals/libpng
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit c1cc0f3f4c3d4abd11ca68c59446a29ff6f95003
|
2
externals/magic_enum
vendored
2
externals/magic_enum
vendored
@ -1 +1 @@
|
||||
Subproject commit 126539e13cccdc2e75ce770e94f3c26403099fa5
|
||||
Subproject commit 1a1824df7ac798177a521eed952720681b0bf482
|
2
externals/pugixml
vendored
2
externals/pugixml
vendored
@ -1 +1 @@
|
||||
Subproject commit 3b17184379fcaaeb7f1fbe08018b7fedf2640b3b
|
||||
Subproject commit 4bc14418d12d289dd9978fdce9490a45deeb653e
|
2
externals/sdl3
vendored
2
externals/sdl3
vendored
@ -1 +1 @@
|
||||
Subproject commit 54e622c2e6af456bfef382fae44c17682d5ac88a
|
||||
Subproject commit a336b62d8b0b97b09214e053203e442e2b6e2be5
|
2
externals/sirit
vendored
2
externals/sirit
vendored
@ -1 +1 @@
|
||||
Subproject commit 6cecb95d679c82c413d1f989e0b7ad9af130600d
|
||||
Subproject commit d6f3c0d99862ab2ff8f95e9ac221560f1f97e29a
|
2
externals/toml11
vendored
2
externals/toml11
vendored
@ -1 +1 @@
|
||||
Subproject commit f925e7f287c0008813c2294798cf9ca167fd9ffd
|
||||
Subproject commit 7f6c574ff5aa1053534e7e19c0a4f22bf4c6aaca
|
2
externals/tracy
vendored
2
externals/tracy
vendored
@ -1 +1 @@
|
||||
Subproject commit b8061982cad0210b649541016c88ff5faa90733c
|
||||
Subproject commit 143a53d1985b8e52a7590a0daca30a0a7c653b42
|
2
externals/vma
vendored
2
externals/vma
vendored
@ -1 +1 @@
|
||||
Subproject commit 1c35ba99ce775f8342d87a83a3f0f696f99c2a39
|
||||
Subproject commit 5a53a198945ba8260fbc58fadb788745ce6aa263
|
2
externals/vulkan-headers
vendored
2
externals/vulkan-headers
vendored
@ -1 +1 @@
|
||||
Subproject commit d91597a82f881d473887b560a03a7edf2720b72c
|
||||
Subproject commit a03d2f6d5753b365d704d58161825890baad0755
|
2
externals/xbyak
vendored
2
externals/xbyak
vendored
@ -1 +1 @@
|
||||
Subproject commit d067f0d3f55696ae8bc9a25ad7012ee80f221d54
|
||||
Subproject commit 4e44f4614ddbf038f2a6296f5b906d5c72691e0f
|
2
externals/xxhash
vendored
2
externals/xxhash
vendored
@ -1 +1 @@
|
||||
Subproject commit d4ad85e4afaad5c780f54db1dc967fff5a869ffd
|
||||
Subproject commit 2bf8313b934633b2a5b7e8fd239645b85e10c852
|
2
externals/zydis
vendored
2
externals/zydis
vendored
@ -1 +1 @@
|
||||
Subproject commit 9d298eb8067ff62a237203d1e1470785033e185c
|
||||
Subproject commit bffbb610cfea643b98e87658b9058382f7522807
|
@ -1,166 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "sdl_audio.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include <SDL3/SDL_init.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
|
||||
#include <mutex> // std::unique_lock
|
||||
|
||||
namespace Audio {
|
||||
|
||||
constexpr int AUDIO_STREAM_BUFFER_THRESHOLD = 65536; // Define constant for buffer threshold
|
||||
|
||||
s32 SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||
Libraries::AudioOut::OrbisAudioOutParamFormat format) {
|
||||
using Libraries::AudioOut::OrbisAudioOutParamFormat;
|
||||
std::unique_lock lock{m_mutex};
|
||||
for (int id = 0; id < portsOut.size(); id++) {
|
||||
auto& port = portsOut[id];
|
||||
if (!port.isOpen) {
|
||||
port.isOpen = true;
|
||||
port.type = type;
|
||||
port.samples_num = samples_num;
|
||||
port.freq = freq;
|
||||
port.format = format;
|
||||
SDL_AudioFormat sampleFormat;
|
||||
switch (format) {
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port.channels_num = 1;
|
||||
port.sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port.channels_num = 1;
|
||||
port.sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port.channels_num = 2;
|
||||
port.sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port.channels_num = 2;
|
||||
port.sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port.channels_num = 8;
|
||||
port.sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port.channels_num = 8;
|
||||
port.sample_size = 4;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD:
|
||||
sampleFormat = SDL_AUDIO_S16;
|
||||
port.channels_num = 8;
|
||||
port.sample_size = 2;
|
||||
break;
|
||||
case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD:
|
||||
sampleFormat = SDL_AUDIO_F32;
|
||||
port.channels_num = 8;
|
||||
port.sample_size = 4;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE_MSG("Unknown format");
|
||||
}
|
||||
|
||||
for (int i = 0; i < port.channels_num; i++) {
|
||||
port.volume[i] = Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB;
|
||||
}
|
||||
|
||||
SDL_AudioSpec fmt;
|
||||
SDL_zero(fmt);
|
||||
fmt.format = sampleFormat;
|
||||
fmt.channels = port.channels_num;
|
||||
fmt.freq = freq; // Set frequency from the argument
|
||||
port.stream =
|
||||
SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL);
|
||||
SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream));
|
||||
return id + 1;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_ERROR(Lib_AudioOut, "Audio ports are full");
|
||||
return ORBIS_AUDIO_OUT_ERROR_PORT_FULL; // all ports are used
|
||||
}
|
||||
|
||||
s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) {
|
||||
std::shared_lock lock{m_mutex};
|
||||
auto& port = portsOut[handle - 1];
|
||||
if (!port.isOpen) {
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
const size_t data_size = port.samples_num * port.sample_size * port.channels_num;
|
||||
|
||||
bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size);
|
||||
|
||||
lock.unlock(); // Unlock only after necessary operations
|
||||
|
||||
while (SDL_GetAudioStreamAvailable(port.stream) > AUDIO_STREAM_BUFFER_THRESHOLD) {
|
||||
SDL_Delay(0);
|
||||
}
|
||||
|
||||
return result ? ORBIS_OK : -1;
|
||||
}
|
||||
|
||||
s32 SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) {
|
||||
using Libraries::AudioOut::OrbisAudioOutParamFormat;
|
||||
std::shared_lock lock{m_mutex};
|
||||
auto& port = portsOut[handle - 1];
|
||||
if (!port.isOpen) {
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u) {
|
||||
auto bit = bitflag & 0x1u;
|
||||
|
||||
if (bit == 1) {
|
||||
int src_index = i;
|
||||
if (port.format ==
|
||||
OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD ||
|
||||
port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) {
|
||||
switch (i) {
|
||||
case 4:
|
||||
src_index = 6;
|
||||
break;
|
||||
case 5:
|
||||
src_index = 7;
|
||||
break;
|
||||
case 6:
|
||||
src_index = 4;
|
||||
break;
|
||||
case 7:
|
||||
src_index = 5;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
port.volume[i] = volume[src_index];
|
||||
}
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 SDLAudio::AudioOutGetStatus(s32 handle, int* type, int* channels_num) {
|
||||
std::shared_lock lock{m_mutex};
|
||||
auto& port = portsOut[handle - 1];
|
||||
*type = port.type;
|
||||
*channels_num = port.channels_num;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
} // namespace Audio
|
@ -1,39 +0,0 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
|
||||
namespace Audio {
|
||||
|
||||
class SDLAudio {
|
||||
public:
|
||||
SDLAudio() = default;
|
||||
virtual ~SDLAudio() = default;
|
||||
|
||||
s32 AudioOutOpen(int type, u32 samples_num, u32 freq,
|
||||
Libraries::AudioOut::OrbisAudioOutParamFormat format);
|
||||
s32 AudioOutOutput(s32 handle, const void* ptr);
|
||||
s32 AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume);
|
||||
s32 AudioOutGetStatus(s32 handle, int* type, int* channels_num);
|
||||
|
||||
private:
|
||||
struct PortOut {
|
||||
SDL_AudioStream* stream = nullptr;
|
||||
u32 samples_num = 0;
|
||||
u32 freq = 0;
|
||||
u32 format = -1;
|
||||
int type = 0;
|
||||
int channels_num = 0;
|
||||
int volume[8] = {};
|
||||
u8 sample_size = 0;
|
||||
bool isOpen = false;
|
||||
};
|
||||
std::shared_mutex m_mutex;
|
||||
std::array<PortOut, Libraries::AudioOut::SCE_AUDIO_OUT_NUM_PORTS> portsOut;
|
||||
};
|
||||
|
||||
} // namespace Audio
|
27
src/common/adaptive_mutex.h
Normal file
27
src/common/adaptive_mutex.h
Normal file
@ -0,0 +1,27 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __linux__
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
class AdaptiveMutex {
|
||||
public:
|
||||
void lock() {
|
||||
pthread_mutex_lock(&mutex);
|
||||
}
|
||||
void unlock() {
|
||||
pthread_mutex_unlock(&mutex);
|
||||
}
|
||||
|
||||
private:
|
||||
pthread_mutex_t mutex = PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP;
|
||||
};
|
||||
#endif // PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
|
||||
} // namespace Common
|
@ -22,6 +22,12 @@ template <typename T>
|
||||
return static_cast<T>(value - value % size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
[[nodiscard]] constexpr bool IsAligned(T value, std::size_t alignment) {
|
||||
return (value & (alignment - 1)) == 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires std::is_integral_v<T>
|
||||
[[nodiscard]] constexpr bool Is16KBAligned(T value) {
|
||||
|
@ -3,13 +3,14 @@
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <common/version.h>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/xchar.h> // for wstring support
|
||||
#include <toml.hpp>
|
||||
#include "common/logging/formatter.h"
|
||||
|
||||
#include "common/path_util.h"
|
||||
#include "config.h"
|
||||
#include "logging/formatter.h"
|
||||
#include "version.h"
|
||||
|
||||
namespace toml {
|
||||
template <typename TC, typename K>
|
||||
@ -32,7 +33,9 @@ namespace Config {
|
||||
|
||||
static bool isNeo = false;
|
||||
static bool isFullscreen = false;
|
||||
static std::string fullscreenMode = "borderless";
|
||||
static bool playBGM = false;
|
||||
static bool isTrophyPopupDisabled = false;
|
||||
static int BGMvolume = 50;
|
||||
static bool enableDiscordRPC = false;
|
||||
static u32 screenWidth = 1280;
|
||||
@ -42,29 +45,40 @@ static std::string logFilter;
|
||||
static std::string logType = "async";
|
||||
static std::string userName = "shadPS4";
|
||||
static std::string updateChannel;
|
||||
static std::string chooseHomeTab;
|
||||
static std::string backButtonBehavior = "left";
|
||||
static bool useSpecialPad = false;
|
||||
static int specialPadClass = 1;
|
||||
static bool isMotionControlsEnabled = true;
|
||||
static bool isDebugDump = false;
|
||||
static bool isShaderDebug = false;
|
||||
static bool isShowSplash = false;
|
||||
static bool isAutoUpdate = false;
|
||||
static bool isNullGpu = false;
|
||||
static bool shouldCopyGPUBuffers = false;
|
||||
static bool shouldDumpShaders = false;
|
||||
static bool shouldPatchShaders = true;
|
||||
static u32 vblankDivider = 1;
|
||||
static bool vkValidation = false;
|
||||
static bool vkValidationSync = false;
|
||||
static bool vkValidationGpu = false;
|
||||
static bool rdocEnable = false;
|
||||
static bool vkMarkers = false;
|
||||
static bool vkCrashDiagnostic = false;
|
||||
static bool vkHostMarkers = false;
|
||||
static bool vkGuestMarkers = false;
|
||||
static bool rdocEnable = false;
|
||||
static s16 cursorState = HideCursorState::Idle;
|
||||
static int cursorHideTimeout = 5; // 5 seconds (default)
|
||||
static bool useUnifiedInputConfig = true;
|
||||
static bool separateupdatefolder = false;
|
||||
static bool compatibilityData = false;
|
||||
static bool checkCompatibilityOnStartup = false;
|
||||
static std::string trophyKey;
|
||||
|
||||
// Gui
|
||||
static bool load_game_size = true;
|
||||
std::vector<std::filesystem::path> settings_install_dirs = {};
|
||||
std::filesystem::path settings_addon_install_dir = {};
|
||||
std::filesystem::path save_data_path = {};
|
||||
u32 main_window_geometry_x = 400;
|
||||
u32 main_window_geometry_y = 400;
|
||||
u32 main_window_geometry_w = 1280;
|
||||
@ -81,17 +95,57 @@ std::vector<std::string> m_pkg_viewer;
|
||||
std::vector<std::string> m_elf_viewer;
|
||||
std::vector<std::string> m_recent_files;
|
||||
std::string emulator_language = "en";
|
||||
// Settings
|
||||
|
||||
// Language
|
||||
u32 m_language = 1; // english
|
||||
|
||||
bool isNeoMode() {
|
||||
bool GetUseUnifiedInputConfig() {
|
||||
return useUnifiedInputConfig;
|
||||
}
|
||||
|
||||
void SetUseUnifiedInputConfig(bool use) {
|
||||
useUnifiedInputConfig = use;
|
||||
}
|
||||
|
||||
std::string getTrophyKey() {
|
||||
return trophyKey;
|
||||
}
|
||||
|
||||
void setTrophyKey(std::string key) {
|
||||
trophyKey = key;
|
||||
}
|
||||
|
||||
bool GetLoadGameSizeEnabled() {
|
||||
return load_game_size;
|
||||
}
|
||||
|
||||
std::filesystem::path GetSaveDataPath() {
|
||||
if (save_data_path.empty()) {
|
||||
return Common::FS::GetUserPath(Common::FS::PathType::SaveDataDir);
|
||||
}
|
||||
return save_data_path;
|
||||
}
|
||||
|
||||
void setLoadGameSizeEnabled(bool enable) {
|
||||
load_game_size = enable;
|
||||
}
|
||||
|
||||
bool isNeoModeConsole() {
|
||||
return isNeo;
|
||||
}
|
||||
|
||||
bool isFullscreenMode() {
|
||||
bool getIsFullscreen() {
|
||||
return isFullscreen;
|
||||
}
|
||||
|
||||
std::string getFullscreenMode() {
|
||||
return fullscreenMode;
|
||||
}
|
||||
|
||||
bool getisTrophyPopupDisabled() {
|
||||
return isTrophyPopupDisabled;
|
||||
}
|
||||
|
||||
bool getPlayBGM() {
|
||||
return playBGM;
|
||||
}
|
||||
@ -140,6 +194,10 @@ std::string getUpdateChannel() {
|
||||
return updateChannel;
|
||||
}
|
||||
|
||||
std::string getChooseHomeTab() {
|
||||
return chooseHomeTab;
|
||||
}
|
||||
|
||||
std::string getBackButtonBehavior() {
|
||||
return backButtonBehavior;
|
||||
}
|
||||
@ -152,10 +210,18 @@ int getSpecialPadClass() {
|
||||
return specialPadClass;
|
||||
}
|
||||
|
||||
bool getIsMotionControlsEnabled() {
|
||||
return isMotionControlsEnabled;
|
||||
}
|
||||
|
||||
bool debugDump() {
|
||||
return isDebugDump;
|
||||
}
|
||||
|
||||
bool collectShadersForDebug() {
|
||||
return isShaderDebug;
|
||||
}
|
||||
|
||||
bool showSplash() {
|
||||
return isShowSplash;
|
||||
}
|
||||
@ -176,12 +242,12 @@ bool dumpShaders() {
|
||||
return shouldDumpShaders;
|
||||
}
|
||||
|
||||
bool isRdocEnabled() {
|
||||
return rdocEnable;
|
||||
bool patchShaders() {
|
||||
return shouldPatchShaders;
|
||||
}
|
||||
|
||||
bool isMarkersEnabled() {
|
||||
return vkMarkers;
|
||||
bool isRdocEnabled() {
|
||||
return rdocEnable;
|
||||
}
|
||||
|
||||
u32 vblankDiv() {
|
||||
@ -200,18 +266,42 @@ bool vkValidationGpuEnabled() {
|
||||
return vkValidationGpu;
|
||||
}
|
||||
|
||||
bool vkMarkersEnabled() {
|
||||
return vkMarkers || vkCrashDiagnostic; // Crash diagnostic forces markers on
|
||||
bool getVkCrashDiagnosticEnabled() {
|
||||
return vkCrashDiagnostic;
|
||||
}
|
||||
|
||||
bool vkCrashDiagnosticEnabled() {
|
||||
return vkCrashDiagnostic;
|
||||
bool getVkHostMarkersEnabled() {
|
||||
return vkHostMarkers;
|
||||
}
|
||||
|
||||
bool getVkGuestMarkersEnabled() {
|
||||
return vkGuestMarkers;
|
||||
}
|
||||
|
||||
void setVkCrashDiagnosticEnabled(bool enable) {
|
||||
vkCrashDiagnostic = enable;
|
||||
}
|
||||
|
||||
void setVkHostMarkersEnabled(bool enable) {
|
||||
vkHostMarkers = enable;
|
||||
}
|
||||
|
||||
void setVkGuestMarkersEnabled(bool enable) {
|
||||
vkGuestMarkers = enable;
|
||||
}
|
||||
|
||||
bool getSeparateUpdateEnabled() {
|
||||
return separateupdatefolder;
|
||||
}
|
||||
|
||||
bool getCompatibilityEnabled() {
|
||||
return compatibilityData;
|
||||
}
|
||||
|
||||
bool getCheckCompatibilityOnStartup() {
|
||||
return checkCompatibilityOnStartup;
|
||||
}
|
||||
|
||||
void setGpuId(s32 selectedGpuId) {
|
||||
gpuId = selectedGpuId;
|
||||
}
|
||||
@ -228,6 +318,10 @@ void setDebugDump(bool enable) {
|
||||
isDebugDump = enable;
|
||||
}
|
||||
|
||||
void setCollectShaderForDebug(bool enable) {
|
||||
isShaderDebug = enable;
|
||||
}
|
||||
|
||||
void setShowSplash(bool enable) {
|
||||
isShowSplash = enable;
|
||||
}
|
||||
@ -264,10 +358,18 @@ void setVblankDiv(u32 value) {
|
||||
vblankDivider = value;
|
||||
}
|
||||
|
||||
void setFullscreenMode(bool enable) {
|
||||
void setIsFullscreen(bool enable) {
|
||||
isFullscreen = enable;
|
||||
}
|
||||
|
||||
void setFullscreenMode(std::string mode) {
|
||||
fullscreenMode = mode;
|
||||
}
|
||||
|
||||
void setisTrophyPopupDisabled(bool disable) {
|
||||
isTrophyPopupDisabled = disable;
|
||||
}
|
||||
|
||||
void setPlayBGM(bool enable) {
|
||||
playBGM = enable;
|
||||
}
|
||||
@ -311,6 +413,9 @@ void setUserName(const std::string& type) {
|
||||
void setUpdateChannel(const std::string& type) {
|
||||
updateChannel = type;
|
||||
}
|
||||
void setChooseHomeTab(const std::string& type) {
|
||||
chooseHomeTab = type;
|
||||
}
|
||||
|
||||
void setBackButtonBehavior(const std::string& type) {
|
||||
backButtonBehavior = type;
|
||||
@ -324,16 +429,29 @@ void setSpecialPadClass(int type) {
|
||||
specialPadClass = type;
|
||||
}
|
||||
|
||||
void setIsMotionControlsEnabled(bool use) {
|
||||
isMotionControlsEnabled = use;
|
||||
}
|
||||
|
||||
void setSeparateUpdateEnabled(bool use) {
|
||||
separateupdatefolder = use;
|
||||
}
|
||||
|
||||
void setCompatibilityEnabled(bool use) {
|
||||
compatibilityData = use;
|
||||
}
|
||||
|
||||
void setCheckCompatibilityOnStartup(bool use) {
|
||||
checkCompatibilityOnStartup = use;
|
||||
}
|
||||
|
||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
||||
main_window_geometry_x = x;
|
||||
main_window_geometry_y = y;
|
||||
main_window_geometry_w = w;
|
||||
main_window_geometry_h = h;
|
||||
}
|
||||
|
||||
bool addGameInstallDir(const std::filesystem::path& dir) {
|
||||
if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) ==
|
||||
settings_install_dirs.end()) {
|
||||
@ -342,47 +460,60 @@ bool addGameInstallDir(const std::filesystem::path& dir) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void removeGameInstallDir(const std::filesystem::path& dir) {
|
||||
auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir);
|
||||
if (iterator != settings_install_dirs.end()) {
|
||||
settings_install_dirs.erase(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
void setAddonInstallDir(const std::filesystem::path& dir) {
|
||||
settings_addon_install_dir = dir;
|
||||
}
|
||||
|
||||
void setMainWindowTheme(u32 theme) {
|
||||
mw_themes = theme;
|
||||
}
|
||||
|
||||
void setIconSize(u32 size) {
|
||||
m_icon_size = size;
|
||||
}
|
||||
|
||||
void setIconSizeGrid(u32 size) {
|
||||
m_icon_size_grid = size;
|
||||
}
|
||||
|
||||
void setSliderPosition(u32 pos) {
|
||||
m_slider_pos = pos;
|
||||
}
|
||||
|
||||
void setSliderPositionGrid(u32 pos) {
|
||||
m_slider_pos_grid = pos;
|
||||
}
|
||||
|
||||
void setTableMode(u32 mode) {
|
||||
m_table_mode = mode;
|
||||
}
|
||||
|
||||
void setMainWindowWidth(u32 width) {
|
||||
m_window_size_W = width;
|
||||
}
|
||||
|
||||
void setMainWindowHeight(u32 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) {
|
||||
m_elf_viewer.resize(elfList.size());
|
||||
m_elf_viewer = elfList;
|
||||
}
|
||||
|
||||
void setRecentFiles(const std::vector<std::string>& recentFiles) {
|
||||
m_recent_files.resize(recentFiles.size());
|
||||
m_recent_files = recentFiles;
|
||||
@ -392,21 +523,34 @@ void setEmulatorLanguage(std::string language) {
|
||||
emulator_language = language;
|
||||
}
|
||||
|
||||
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config) {
|
||||
settings_install_dirs = settings_install_dirs_config;
|
||||
}
|
||||
|
||||
void setSaveDataPath(const std::filesystem::path& path) {
|
||||
save_data_path = path;
|
||||
}
|
||||
|
||||
u32 getMainWindowGeometryX() {
|
||||
return main_window_geometry_x;
|
||||
}
|
||||
|
||||
u32 getMainWindowGeometryY() {
|
||||
return main_window_geometry_y;
|
||||
}
|
||||
|
||||
u32 getMainWindowGeometryW() {
|
||||
return main_window_geometry_w;
|
||||
}
|
||||
|
||||
u32 getMainWindowGeometryH() {
|
||||
return main_window_geometry_h;
|
||||
}
|
||||
|
||||
const std::vector<std::filesystem::path>& getGameInstallDirs() {
|
||||
return settings_install_dirs;
|
||||
}
|
||||
|
||||
std::filesystem::path getAddonInstallDir() {
|
||||
if (settings_addon_install_dir.empty()) {
|
||||
// Default for users without a config file or a config file from before this option existed
|
||||
@ -414,36 +558,47 @@ std::filesystem::path getAddonInstallDir() {
|
||||
}
|
||||
return settings_addon_install_dir;
|
||||
}
|
||||
|
||||
u32 getMainWindowTheme() {
|
||||
return mw_themes;
|
||||
}
|
||||
|
||||
u32 getIconSize() {
|
||||
return m_icon_size;
|
||||
}
|
||||
|
||||
u32 getIconSizeGrid() {
|
||||
return m_icon_size_grid;
|
||||
}
|
||||
|
||||
u32 getSliderPosition() {
|
||||
return m_slider_pos;
|
||||
}
|
||||
|
||||
u32 getSliderPositionGrid() {
|
||||
return m_slider_pos_grid;
|
||||
}
|
||||
|
||||
u32 getTableMode() {
|
||||
return m_table_mode;
|
||||
}
|
||||
|
||||
u32 getMainWindowWidth() {
|
||||
return m_window_size_W;
|
||||
}
|
||||
|
||||
u32 getMainWindowHeight() {
|
||||
return m_window_size_H;
|
||||
}
|
||||
|
||||
std::vector<std::string> getPkgViewer() {
|
||||
return m_pkg_viewer;
|
||||
}
|
||||
|
||||
std::vector<std::string> getElfViewer() {
|
||||
return m_elf_viewer;
|
||||
}
|
||||
|
||||
std::vector<std::string> getRecentFiles() {
|
||||
return m_recent_files;
|
||||
}
|
||||
@ -455,6 +610,7 @@ std::string getEmulatorLanguage() {
|
||||
u32 GetLanguage() {
|
||||
return m_language;
|
||||
}
|
||||
|
||||
void load(const std::filesystem::path& path) {
|
||||
// If the configuration file does not exist, create it and return
|
||||
std::error_code error;
|
||||
@ -479,7 +635,9 @@ void load(const std::filesystem::path& path) {
|
||||
|
||||
isNeo = toml::find_or<bool>(general, "isPS4Pro", false);
|
||||
isFullscreen = toml::find_or<bool>(general, "Fullscreen", false);
|
||||
fullscreenMode = toml::find_or<std::string>(general, "FullscreenMode", "borderless");
|
||||
playBGM = toml::find_or<bool>(general, "playBGM", false);
|
||||
isTrophyPopupDisabled = toml::find_or<bool>(general, "isTrophyPopupDisabled", false);
|
||||
BGMvolume = toml::find_or<int>(general, "BGMvolume", 50);
|
||||
enableDiscordRPC = toml::find_or<bool>(general, "enableDiscordRPC", true);
|
||||
logFilter = toml::find_or<std::string>(general, "logFilter", "");
|
||||
@ -493,6 +651,10 @@ void load(const std::filesystem::path& path) {
|
||||
isShowSplash = toml::find_or<bool>(general, "showSplash", true);
|
||||
isAutoUpdate = toml::find_or<bool>(general, "autoUpdate", false);
|
||||
separateupdatefolder = toml::find_or<bool>(general, "separateUpdateEnabled", false);
|
||||
compatibilityData = toml::find_or<bool>(general, "compatibilityEnabled", false);
|
||||
checkCompatibilityOnStartup =
|
||||
toml::find_or<bool>(general, "checkCompatibilityOnStartup", false);
|
||||
chooseHomeTab = toml::find_or<std::string>(general, "chooseHomeTab", "Release");
|
||||
}
|
||||
|
||||
if (data.contains("Input")) {
|
||||
@ -503,6 +665,8 @@ void load(const std::filesystem::path& path) {
|
||||
backButtonBehavior = toml::find_or<std::string>(input, "backButtonBehavior", "left");
|
||||
useSpecialPad = toml::find_or<bool>(input, "useSpecialPad", false);
|
||||
specialPadClass = toml::find_or<int>(input, "specialPadClass", 1);
|
||||
isMotionControlsEnabled = toml::find_or<bool>(input, "isMotionControlsEnabled", true);
|
||||
useUnifiedInputConfig = toml::find_or<bool>(input, "useUnifiedInputConfig", true);
|
||||
}
|
||||
|
||||
if (data.contains("GPU")) {
|
||||
@ -513,6 +677,7 @@ void load(const std::filesystem::path& path) {
|
||||
isNullGpu = toml::find_or<bool>(gpu, "nullGpu", false);
|
||||
shouldCopyGPUBuffers = toml::find_or<bool>(gpu, "copyGPUBuffers", false);
|
||||
shouldDumpShaders = toml::find_or<bool>(gpu, "dumpShaders", false);
|
||||
shouldPatchShaders = toml::find_or<bool>(gpu, "patchShaders", true);
|
||||
vblankDivider = toml::find_or<int>(gpu, "vblankDivider", 1);
|
||||
}
|
||||
|
||||
@ -523,20 +688,23 @@ void load(const std::filesystem::path& path) {
|
||||
vkValidation = toml::find_or<bool>(vk, "validation", false);
|
||||
vkValidationSync = toml::find_or<bool>(vk, "validation_sync", false);
|
||||
vkValidationGpu = toml::find_or<bool>(vk, "validation_gpu", true);
|
||||
rdocEnable = toml::find_or<bool>(vk, "rdocEnable", false);
|
||||
vkMarkers = toml::find_or<bool>(vk, "rdocMarkersEnable", false);
|
||||
vkCrashDiagnostic = toml::find_or<bool>(vk, "crashDiagnostic", false);
|
||||
vkHostMarkers = toml::find_or<bool>(vk, "hostMarkers", false);
|
||||
vkGuestMarkers = toml::find_or<bool>(vk, "guestMarkers", false);
|
||||
rdocEnable = toml::find_or<bool>(vk, "rdocEnable", false);
|
||||
}
|
||||
|
||||
if (data.contains("Debug")) {
|
||||
const toml::value& debug = data.at("Debug");
|
||||
|
||||
isDebugDump = toml::find_or<bool>(debug, "DebugDump", false);
|
||||
isShaderDebug = toml::find_or<bool>(debug, "CollectShader", false);
|
||||
}
|
||||
|
||||
if (data.contains("GUI")) {
|
||||
const toml::value& gui = data.at("GUI");
|
||||
|
||||
load_game_size = toml::find_or<bool>(gui, "loadGameSizeEnabled", true);
|
||||
m_icon_size = toml::find_or<int>(gui, "iconSize", 0);
|
||||
m_icon_size_grid = toml::find_or<int>(gui, "iconSizeGrid", 0);
|
||||
m_slider_pos = toml::find_or<int>(gui, "sliderPos", 0);
|
||||
@ -545,18 +713,14 @@ void load(const std::filesystem::path& path) {
|
||||
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
||||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||
|
||||
// TODO Migration code, after a major release this should be removed.
|
||||
auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
||||
if (!old_game_install_dir.empty()) {
|
||||
addGameInstallDir(std::filesystem::path{old_game_install_dir});
|
||||
} else {
|
||||
const auto install_dir_array =
|
||||
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||
for (const auto& dir : install_dir_array) {
|
||||
addGameInstallDir(std::filesystem::path{dir});
|
||||
}
|
||||
const auto install_dir_array =
|
||||
toml::find_or<std::vector<std::string>>(gui, "installDirs", {});
|
||||
for (const auto& dir : install_dir_array) {
|
||||
addGameInstallDir(std::filesystem::path{dir});
|
||||
}
|
||||
|
||||
save_data_path = toml::find_fs_path_or(gui, "saveDataPath", {});
|
||||
|
||||
settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {});
|
||||
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||
@ -574,7 +738,13 @@ void load(const std::filesystem::path& path) {
|
||||
|
||||
m_language = toml::find_or<int>(settings, "consoleLanguage", 1);
|
||||
}
|
||||
|
||||
if (data.contains("Keys")) {
|
||||
const toml::value& keys = data.at("Keys");
|
||||
trophyKey = toml::find_or<std::string>(keys, "TrophyKey", "");
|
||||
}
|
||||
}
|
||||
|
||||
void save(const std::filesystem::path& path) {
|
||||
toml::value data;
|
||||
|
||||
@ -598,6 +768,8 @@ void save(const std::filesystem::path& path) {
|
||||
|
||||
data["General"]["isPS4Pro"] = isNeo;
|
||||
data["General"]["Fullscreen"] = isFullscreen;
|
||||
data["General"]["FullscreenMode"] = fullscreenMode;
|
||||
data["General"]["isTrophyPopupDisabled"] = isTrophyPopupDisabled;
|
||||
data["General"]["playBGM"] = playBGM;
|
||||
data["General"]["BGMvolume"] = BGMvolume;
|
||||
data["General"]["enableDiscordRPC"] = enableDiscordRPC;
|
||||
@ -605,45 +777,87 @@ void save(const std::filesystem::path& path) {
|
||||
data["General"]["logType"] = logType;
|
||||
data["General"]["userName"] = userName;
|
||||
data["General"]["updateChannel"] = updateChannel;
|
||||
data["General"]["chooseHomeTab"] = chooseHomeTab;
|
||||
data["General"]["showSplash"] = isShowSplash;
|
||||
data["General"]["autoUpdate"] = isAutoUpdate;
|
||||
data["General"]["separateUpdateEnabled"] = separateupdatefolder;
|
||||
data["General"]["compatibilityEnabled"] = compatibilityData;
|
||||
data["General"]["checkCompatibilityOnStartup"] = checkCompatibilityOnStartup;
|
||||
data["Input"]["cursorState"] = cursorState;
|
||||
data["Input"]["cursorHideTimeout"] = cursorHideTimeout;
|
||||
data["Input"]["backButtonBehavior"] = backButtonBehavior;
|
||||
data["Input"]["useSpecialPad"] = useSpecialPad;
|
||||
data["Input"]["specialPadClass"] = specialPadClass;
|
||||
data["Input"]["isMotionControlsEnabled"] = isMotionControlsEnabled;
|
||||
data["Input"]["useUnifiedInputConfig"] = useUnifiedInputConfig;
|
||||
data["GPU"]["screenWidth"] = screenWidth;
|
||||
data["GPU"]["screenHeight"] = screenHeight;
|
||||
data["GPU"]["nullGpu"] = isNullGpu;
|
||||
data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers;
|
||||
data["GPU"]["dumpShaders"] = shouldDumpShaders;
|
||||
data["GPU"]["patchShaders"] = shouldPatchShaders;
|
||||
data["GPU"]["vblankDivider"] = vblankDivider;
|
||||
data["Vulkan"]["gpuId"] = gpuId;
|
||||
data["Vulkan"]["validation"] = vkValidation;
|
||||
data["Vulkan"]["validation_sync"] = vkValidationSync;
|
||||
data["Vulkan"]["validation_gpu"] = vkValidationGpu;
|
||||
data["Vulkan"]["rdocEnable"] = rdocEnable;
|
||||
data["Vulkan"]["rdocMarkersEnable"] = vkMarkers;
|
||||
data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic;
|
||||
data["Vulkan"]["hostMarkers"] = vkHostMarkers;
|
||||
data["Vulkan"]["guestMarkers"] = vkGuestMarkers;
|
||||
data["Vulkan"]["rdocEnable"] = rdocEnable;
|
||||
data["Debug"]["DebugDump"] = isDebugDump;
|
||||
data["GUI"]["theme"] = mw_themes;
|
||||
data["GUI"]["iconSize"] = m_icon_size;
|
||||
data["GUI"]["sliderPos"] = m_slider_pos;
|
||||
data["GUI"]["iconSizeGrid"] = m_icon_size_grid;
|
||||
data["GUI"]["sliderPosGrid"] = m_slider_pos_grid;
|
||||
data["GUI"]["gameTableMode"] = m_table_mode;
|
||||
data["GUI"]["mw_width"] = m_window_size_W;
|
||||
data["GUI"]["mw_height"] = m_window_size_H;
|
||||
data["Debug"]["CollectShader"] = isShaderDebug;
|
||||
|
||||
data["Keys"]["TrophyKey"] = trophyKey;
|
||||
|
||||
std::vector<std::string> install_dirs;
|
||||
for (const auto& dirString : settings_install_dirs) {
|
||||
install_dirs.emplace_back(std::string{fmt::UTF(dirString.u8string()).data});
|
||||
}
|
||||
data["GUI"]["installDirs"] = install_dirs;
|
||||
data["GUI"]["saveDataPath"] = std::string{fmt::UTF(save_data_path.u8string()).data};
|
||||
data["GUI"]["loadGameSizeEnabled"] = load_game_size;
|
||||
|
||||
data["GUI"]["addonInstallDir"] =
|
||||
std::string{fmt::UTF(settings_addon_install_dir.u8string()).data};
|
||||
data["GUI"]["emulatorLanguage"] = emulator_language;
|
||||
data["Settings"]["consoleLanguage"] = m_language;
|
||||
|
||||
std::ofstream file(path, std::ios::binary);
|
||||
file << data;
|
||||
file.close();
|
||||
saveMainWindow(path);
|
||||
}
|
||||
|
||||
void saveMainWindow(const std::filesystem::path& path) {
|
||||
toml::value data;
|
||||
|
||||
std::error_code error;
|
||||
if (std::filesystem::exists(path, error)) {
|
||||
try {
|
||||
std::ifstream ifs;
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
ifs.open(path, std::ios_base::binary);
|
||||
data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data});
|
||||
} catch (const std::exception& ex) {
|
||||
fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (error) {
|
||||
fmt::print("Filesystem error: {}\n", error.message());
|
||||
}
|
||||
fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string()));
|
||||
}
|
||||
|
||||
data["GUI"]["mw_width"] = m_window_size_W;
|
||||
data["GUI"]["mw_height"] = m_window_size_H;
|
||||
data["GUI"]["theme"] = mw_themes;
|
||||
data["GUI"]["iconSize"] = m_icon_size;
|
||||
data["GUI"]["sliderPos"] = m_slider_pos;
|
||||
data["GUI"]["iconSizeGrid"] = m_icon_size_grid;
|
||||
data["GUI"]["sliderPosGrid"] = m_slider_pos_grid;
|
||||
data["GUI"]["gameTableMode"] = m_table_mode;
|
||||
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
||||
data["GUI"]["geometry_y"] = main_window_geometry_y;
|
||||
data["GUI"]["geometry_w"] = main_window_geometry_w;
|
||||
@ -651,14 +865,8 @@ void save(const std::filesystem::path& path) {
|
||||
data["GUI"]["pkgDirs"] = m_pkg_viewer;
|
||||
data["GUI"]["elfDirs"] = m_elf_viewer;
|
||||
data["GUI"]["recentFiles"] = m_recent_files;
|
||||
data["GUI"]["emulatorLanguage"] = emulator_language;
|
||||
|
||||
data["Settings"]["consoleLanguage"] = m_language;
|
||||
|
||||
// TODO Migration code, after a major release this should be removed.
|
||||
data.at("GUI").as_table().erase("installDir");
|
||||
|
||||
std::ofstream file(path, std::ios::out);
|
||||
std::ofstream file(path, std::ios::binary);
|
||||
file << data;
|
||||
file.close();
|
||||
}
|
||||
@ -666,6 +874,7 @@ void save(const std::filesystem::path& path) {
|
||||
void setDefaultValues() {
|
||||
isNeo = false;
|
||||
isFullscreen = false;
|
||||
isTrophyPopupDisabled = false;
|
||||
playBGM = false;
|
||||
BGMvolume = 50;
|
||||
enableDiscordRPC = true;
|
||||
@ -679,12 +888,14 @@ void setDefaultValues() {
|
||||
} else {
|
||||
updateChannel = "Nightly";
|
||||
}
|
||||
chooseHomeTab = "General";
|
||||
cursorState = HideCursorState::Idle;
|
||||
cursorHideTimeout = 5;
|
||||
backButtonBehavior = "left";
|
||||
useSpecialPad = false;
|
||||
specialPadClass = 1;
|
||||
isDebugDump = false;
|
||||
isShaderDebug = false;
|
||||
isShowSplash = false;
|
||||
isAutoUpdate = false;
|
||||
isNullGpu = false;
|
||||
@ -693,12 +904,124 @@ void setDefaultValues() {
|
||||
vkValidation = false;
|
||||
vkValidationSync = false;
|
||||
vkValidationGpu = false;
|
||||
rdocEnable = false;
|
||||
vkMarkers = false;
|
||||
vkCrashDiagnostic = false;
|
||||
vkHostMarkers = false;
|
||||
vkGuestMarkers = false;
|
||||
rdocEnable = false;
|
||||
emulator_language = "en";
|
||||
m_language = 1;
|
||||
gpuId = -1;
|
||||
separateupdatefolder = false;
|
||||
compatibilityData = false;
|
||||
checkCompatibilityOnStartup = false;
|
||||
}
|
||||
|
||||
constexpr std::string_view GetDefaultKeyboardConfig() {
|
||||
return R"(#Feeling lost? Check out the Help section!
|
||||
|
||||
# Keyboard bindings
|
||||
|
||||
triangle = kp8
|
||||
circle = kp6
|
||||
cross = kp2
|
||||
square = kp4
|
||||
# Alternatives for users without a keypad
|
||||
triangle = c
|
||||
circle = b
|
||||
cross = n
|
||||
square = v
|
||||
|
||||
l1 = q
|
||||
r1 = u
|
||||
l2 = e
|
||||
r2 = o
|
||||
l3 = x
|
||||
r3 = m
|
||||
|
||||
options = enter
|
||||
touchpad = space
|
||||
|
||||
pad_up = up
|
||||
pad_down = down
|
||||
pad_left = left
|
||||
pad_right = right
|
||||
|
||||
axis_left_x_minus = a
|
||||
axis_left_x_plus = d
|
||||
axis_left_y_minus = w
|
||||
axis_left_y_plus = s
|
||||
|
||||
axis_right_x_minus = j
|
||||
axis_right_x_plus = l
|
||||
axis_right_y_minus = i
|
||||
axis_right_y_plus = k
|
||||
|
||||
# Controller bindings
|
||||
|
||||
triangle = triangle
|
||||
cross = cross
|
||||
square = square
|
||||
circle = circle
|
||||
|
||||
l1 = l1
|
||||
l2 = l2
|
||||
l3 = l3
|
||||
r1 = r1
|
||||
r2 = r2
|
||||
r3 = r3
|
||||
|
||||
options = options
|
||||
touchpad = back
|
||||
|
||||
pad_up = pad_up
|
||||
pad_down = pad_down
|
||||
pad_left = pad_left
|
||||
pad_right = pad_right
|
||||
|
||||
axis_left_x = axis_left_x
|
||||
axis_left_y = axis_left_y
|
||||
axis_right_x = axis_right_x
|
||||
axis_right_y = axis_right_y
|
||||
|
||||
# Range of deadzones: 1 (almost none) to 127 (max)
|
||||
analog_deadzone = leftjoystick, 2
|
||||
analog_deadzone = rightjoystick, 2
|
||||
)";
|
||||
}
|
||||
std::filesystem::path GetFoolproofKbmConfigFile(const std::string& game_id) {
|
||||
// Read configuration file of the game, and if it doesn't exist, generate it from default
|
||||
// If that doesn't exist either, generate that from getDefaultConfig() and try again
|
||||
// If even the folder is missing, we start with that.
|
||||
|
||||
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "input_config";
|
||||
const auto config_file = config_dir / (game_id + ".ini");
|
||||
const auto default_config_file = config_dir / "default.ini";
|
||||
|
||||
// Ensure the config directory exists
|
||||
if (!std::filesystem::exists(config_dir)) {
|
||||
std::filesystem::create_directories(config_dir);
|
||||
}
|
||||
|
||||
// Check if the default config exists
|
||||
if (!std::filesystem::exists(default_config_file)) {
|
||||
// If the default config is also missing, create it from getDefaultConfig()
|
||||
const auto default_config = GetDefaultKeyboardConfig();
|
||||
std::ofstream default_config_stream(default_config_file);
|
||||
if (default_config_stream) {
|
||||
default_config_stream << default_config;
|
||||
}
|
||||
}
|
||||
|
||||
// if empty, we only need to execute the function up until this point
|
||||
if (game_id.empty()) {
|
||||
return default_config_file;
|
||||
}
|
||||
|
||||
// If game-specific config doesn't exist, create it from the default config
|
||||
if (!std::filesystem::exists(config_file)) {
|
||||
std::filesystem::copy(default_config_file, config_file);
|
||||
}
|
||||
return config_file;
|
||||
}
|
||||
|
||||
} // namespace Config
|
||||
|
@ -13,39 +13,56 @@ enum HideCursorState : s16 { Never, Idle, Always };
|
||||
|
||||
void load(const std::filesystem::path& path);
|
||||
void save(const std::filesystem::path& path);
|
||||
void saveMainWindow(const std::filesystem::path& path);
|
||||
|
||||
bool isNeoMode();
|
||||
bool isFullscreenMode();
|
||||
std::string getTrophyKey();
|
||||
void setTrophyKey(std::string key);
|
||||
bool GetLoadGameSizeEnabled();
|
||||
std::filesystem::path GetSaveDataPath();
|
||||
void setLoadGameSizeEnabled(bool enable);
|
||||
bool getIsFullscreen();
|
||||
std::string getFullscreenMode();
|
||||
bool isNeoModeConsole();
|
||||
bool getPlayBGM();
|
||||
int getBGMvolume();
|
||||
bool getisTrophyPopupDisabled();
|
||||
bool getEnableDiscordRPC();
|
||||
bool getSeparateUpdateEnabled();
|
||||
bool getCompatibilityEnabled();
|
||||
bool getCheckCompatibilityOnStartup();
|
||||
|
||||
std::string getLogFilter();
|
||||
std::string getLogType();
|
||||
std::string getUserName();
|
||||
std::string getUpdateChannel();
|
||||
std::string getChooseHomeTab();
|
||||
|
||||
s16 getCursorState();
|
||||
int getCursorHideTimeout();
|
||||
std::string getBackButtonBehavior();
|
||||
bool getUseSpecialPad();
|
||||
int getSpecialPadClass();
|
||||
bool getIsMotionControlsEnabled();
|
||||
bool GetUseUnifiedInputConfig();
|
||||
void SetUseUnifiedInputConfig(bool use);
|
||||
|
||||
u32 getScreenWidth();
|
||||
u32 getScreenHeight();
|
||||
s32 getGpuId();
|
||||
|
||||
bool debugDump();
|
||||
bool collectShadersForDebug();
|
||||
bool showSplash();
|
||||
bool autoUpdate();
|
||||
bool nullGpu();
|
||||
bool copyGPUCmdBuffers();
|
||||
bool dumpShaders();
|
||||
bool patchShaders();
|
||||
bool isRdocEnabled();
|
||||
u32 vblankDiv();
|
||||
|
||||
void setDebugDump(bool enable);
|
||||
void setCollectShaderForDebug(bool enable);
|
||||
void setShowSplash(bool enable);
|
||||
void setAutoUpdate(bool enable);
|
||||
void setNullGpu(bool enable);
|
||||
@ -55,7 +72,9 @@ void setVblankDiv(u32 value);
|
||||
void setGpuId(s32 selectedGpuId);
|
||||
void setScreenWidth(u32 width);
|
||||
void setScreenHeight(u32 height);
|
||||
void setFullscreenMode(bool enable);
|
||||
void setIsFullscreen(bool enable);
|
||||
void setFullscreenMode(std::string mode);
|
||||
void setisTrophyPopupDisabled(bool disable);
|
||||
void setPlayBGM(bool enable);
|
||||
void setBGMvolume(int volume);
|
||||
void setEnableDiscordRPC(bool enable);
|
||||
@ -63,13 +82,19 @@ void setLanguage(u32 language);
|
||||
void setNeoMode(bool enable);
|
||||
void setUserName(const std::string& type);
|
||||
void setUpdateChannel(const std::string& type);
|
||||
void setChooseHomeTab(const std::string& type);
|
||||
void setSeparateUpdateEnabled(bool use);
|
||||
void setGameInstallDirs(const std::vector<std::filesystem::path>& settings_install_dirs_config);
|
||||
void setSaveDataPath(const std::filesystem::path& path);
|
||||
void setCompatibilityEnabled(bool use);
|
||||
void setCheckCompatibilityOnStartup(bool use);
|
||||
|
||||
void setCursorState(s16 cursorState);
|
||||
void setCursorHideTimeout(int newcursorHideTimeout);
|
||||
void setBackButtonBehavior(const std::string& type);
|
||||
void setUseSpecialPad(bool use);
|
||||
void setSpecialPadClass(int type);
|
||||
void setIsMotionControlsEnabled(bool use);
|
||||
|
||||
void setLogType(const std::string& type);
|
||||
void setLogFilter(const std::string& type);
|
||||
@ -81,8 +106,12 @@ void setRdocEnabled(bool enable);
|
||||
bool vkValidationEnabled();
|
||||
bool vkValidationSyncEnabled();
|
||||
bool vkValidationGpuEnabled();
|
||||
bool vkMarkersEnabled();
|
||||
bool vkCrashDiagnosticEnabled();
|
||||
bool getVkCrashDiagnosticEnabled();
|
||||
bool getVkHostMarkersEnabled();
|
||||
bool getVkGuestMarkersEnabled();
|
||||
void setVkCrashDiagnosticEnabled(bool enable);
|
||||
void setVkHostMarkersEnabled(bool enable);
|
||||
void setVkGuestMarkersEnabled(bool enable);
|
||||
|
||||
// Gui
|
||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
||||
@ -123,6 +152,9 @@ std::string getEmulatorLanguage();
|
||||
|
||||
void setDefaultValues();
|
||||
|
||||
// todo: name and function location pending
|
||||
std::filesystem::path GetFoolproofKbmConfigFile(const std::string& game_id = "");
|
||||
|
||||
// settings
|
||||
u32 GetLanguage();
|
||||
}; // namespace Config
|
||||
|
@ -14,9 +14,15 @@
|
||||
#include <tracy/Tracy.hpp>
|
||||
|
||||
static inline bool IsProfilerConnected() {
|
||||
#if TRACY_ENABLE
|
||||
return tracy::GetProfiler().IsConnected();
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TRACY_GPU_ENABLED 0
|
||||
|
||||
#define CUSTOM_LOCK(type, varname) \
|
||||
tracy::LockableCtx varname { \
|
||||
[]() -> const tracy::SourceLocationData* { \
|
||||
@ -41,7 +47,7 @@ enum MarkersPalette : int {
|
||||
#define RENDERER_TRACE ZoneScopedC(RendererMarkerColor)
|
||||
#define HLE_TRACE ZoneScopedC(HleMarkerColor)
|
||||
|
||||
#define TRACE_HINT(str) ZoneText(str.c_str(), str.size())
|
||||
#define TRACE_HINT(str) ZoneText(str.data(), str.size())
|
||||
|
||||
#define TRACE_WARN(msg) \
|
||||
[](const auto& msg) { TracyMessageC(msg.c_str(), msg.size(), tracy::Color::DarkOrange); }(msg);
|
||||
@ -57,3 +63,11 @@ enum MarkersPalette : int {
|
||||
tracy::SourceLocationData{nullptr, name, TracyFile, (uint32_t)TracyLine, 0};
|
||||
|
||||
#define FRAME_END FrameMark
|
||||
|
||||
#ifdef TRACY_FIBERS
|
||||
#define FIBER_ENTER(name) TracyFiberEnter(name)
|
||||
#define FIBER_EXIT TracyFiberLeave
|
||||
#else
|
||||
#define FIBER_ENTER(name)
|
||||
#define FIBER_EXIT
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include "src/common/discord_rpc_handler.h"
|
||||
#include "discord_rpc_handler.h"
|
||||
|
||||
namespace DiscordRPCHandler {
|
||||
|
||||
@ -17,7 +17,7 @@ void RPC::init() {
|
||||
|
||||
void RPC::setStatusIdling() {
|
||||
DiscordRichPresence rpc{};
|
||||
rpc.largeImageKey = "https://github.com/shadps4-emu/shadPS4/raw/main/.github/shadps4.png";
|
||||
rpc.largeImageKey = "https://cdn.jsdelivr.net/gh/shadps4-emu/shadPS4@main/.github/shadps4.png";
|
||||
rpc.largeImageText = "shadPS4 is a PS4 emulator";
|
||||
rpc.startTimestamp = startTimestamp;
|
||||
rpc.details = "Idle";
|
||||
|
@ -1,25 +1,25 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// Ceiled integer division.
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
|
||||
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
|
||||
}
|
||||
|
||||
/// Ceiled integer division with logarithmic divisor in base 2
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
|
||||
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// Ceiled integer division.
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||
[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
|
||||
return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
|
||||
}
|
||||
|
||||
/// Ceiled integer division with logarithmic divisor in base 2
|
||||
template <typename N, typename D>
|
||||
requires std::is_integral_v<N> && std::is_unsigned_v<D>
|
||||
[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
|
||||
return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string_view>
|
||||
|
||||
#include "assert.h"
|
||||
#include "bit_field.h"
|
||||
#include "singleton.h"
|
||||
#include "types.h"
|
||||
|
||||
@ -16,6 +17,46 @@ class Emulator;
|
||||
|
||||
namespace Common {
|
||||
|
||||
union PSFAttributes {
|
||||
/// Supports initial user's logout
|
||||
BitField<0, 1, u32> support_initial_user_logout;
|
||||
/// Enter button for the common dialog is cross.
|
||||
BitField<1, 1, u32> enter_button_cross;
|
||||
/// Warning dialog for PS Move is displayed in the options menu.
|
||||
BitField<2, 1, u32> ps_move_warning;
|
||||
/// Supports stereoscopic 3D.
|
||||
BitField<3, 1, u32> support_stereoscopic_3d;
|
||||
/// Suspends when PS button is pressed.
|
||||
BitField<4, 1, u32> ps_button_suspend;
|
||||
/// Enter button for the common dialog is assigned by the system software.
|
||||
BitField<5, 1, u32> enter_button_system;
|
||||
/// Overrides share menu behavior.
|
||||
BitField<6, 1, u32> override_share_menu;
|
||||
/// Suspends when PS button is pressed and special output resolution is set.
|
||||
BitField<8, 1, u32> special_res_ps_button_suspend;
|
||||
/// Enable HDCP.
|
||||
BitField<9, 1, u32> enable_hdcp;
|
||||
/// Disable HDCP for non-game.
|
||||
BitField<10, 1, u32> disable_hdcp_non_game;
|
||||
/// Supports PS VR.
|
||||
BitField<14, 1, u32> support_ps_vr;
|
||||
/// CPU mode (6 CPU)
|
||||
BitField<15, 1, u32> six_cpu_mode;
|
||||
/// CPU mode (7 CPU)
|
||||
BitField<16, 1, u32> seven_cpu_mode;
|
||||
/// Supports PS4 Pro (Neo) mode.
|
||||
BitField<23, 1, u32> support_neo_mode;
|
||||
/// Requires PS VR.
|
||||
BitField<26, 1, u32> require_ps_vr;
|
||||
/// Supports HDR.
|
||||
BitField<29, 1, u32> support_hdr;
|
||||
/// Display location.
|
||||
BitField<31, 1, u32> display_location;
|
||||
|
||||
u32 raw{};
|
||||
};
|
||||
static_assert(sizeof(PSFAttributes) == 4);
|
||||
|
||||
class ElfInfo {
|
||||
friend class Core::Emulator;
|
||||
|
||||
@ -26,6 +67,7 @@ class ElfInfo {
|
||||
std::string app_ver{};
|
||||
u32 firmware_ver = 0;
|
||||
u32 raw_firmware_ver = 0;
|
||||
PSFAttributes psf_attributes{};
|
||||
|
||||
public:
|
||||
static constexpr u32 FW_15 = 0x1500000;
|
||||
@ -34,9 +76,11 @@ public:
|
||||
static constexpr u32 FW_20 = 0x2000000;
|
||||
static constexpr u32 FW_25 = 0x2500000;
|
||||
static constexpr u32 FW_30 = 0x3000000;
|
||||
static constexpr u32 FW_35 = 0x3500000;
|
||||
static constexpr u32 FW_40 = 0x4000000;
|
||||
static constexpr u32 FW_45 = 0x4500000;
|
||||
static constexpr u32 FW_50 = 0x5000000;
|
||||
static constexpr u32 FW_55 = 0x5500000;
|
||||
static constexpr u32 FW_80 = 0x8000000;
|
||||
|
||||
static ElfInfo& Instance() {
|
||||
@ -67,6 +111,11 @@ public:
|
||||
ASSERT(initialized);
|
||||
return raw_firmware_ver;
|
||||
}
|
||||
|
||||
[[nodiscard]] const PSFAttributes& GetPSFAttributes() const {
|
||||
ASSERT(initialized);
|
||||
return psf_attributes;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
@ -377,16 +377,18 @@ bool IOFile::Seek(s64 offset, SeekOrigin origin) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "common/concepts.h"
|
||||
#include "common/types.h"
|
||||
#include "enum.h"
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
@ -42,6 +43,7 @@ enum class FileAccessMode {
|
||||
*/
|
||||
ReadAppend = Read | Append,
|
||||
};
|
||||
DECLARE_ENUM_FLAG_OPERATORS(FileAccessMode);
|
||||
|
||||
enum class FileType {
|
||||
BinaryFile,
|
||||
@ -205,7 +207,7 @@ public:
|
||||
return WriteSpan(string);
|
||||
}
|
||||
|
||||
static size_t WriteBytes(const std::filesystem::path path, std::span<const u8> data) {
|
||||
static size_t WriteBytes(const std::filesystem::path path, const auto& data) {
|
||||
IOFile out(path, FileAccessMode::Write);
|
||||
return out.Write(data);
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
SUB(Common, Memory) \
|
||||
CLS(Core) \
|
||||
SUB(Core, Linker) \
|
||||
SUB(Core, Devices) \
|
||||
CLS(Config) \
|
||||
CLS(Debug) \
|
||||
CLS(Kernel) \
|
||||
@ -94,18 +95,25 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
SUB(Lib, SaveData) \
|
||||
SUB(Lib, SaveDataDialog) \
|
||||
SUB(Lib, Http) \
|
||||
SUB(Lib, Http2) \
|
||||
SUB(Lib, Ssl) \
|
||||
SUB(Lib, Ssl2) \
|
||||
SUB(Lib, SysModule) \
|
||||
SUB(Lib, Move) \
|
||||
SUB(Lib, NpCommon) \
|
||||
SUB(Lib, NpManager) \
|
||||
SUB(Lib, NpScore) \
|
||||
SUB(Lib, NpTrophy) \
|
||||
SUB(Lib, NpWebApi) \
|
||||
SUB(Lib, Screenshot) \
|
||||
SUB(Lib, LibCInternal) \
|
||||
SUB(Lib, AppContent) \
|
||||
SUB(Lib, Rtc) \
|
||||
SUB(Lib, DiscMap) \
|
||||
SUB(Lib, Png) \
|
||||
SUB(Lib, Jpeg) \
|
||||
SUB(Lib, PlayGo) \
|
||||
SUB(Lib, PlayGoDialog) \
|
||||
SUB(Lib, Random) \
|
||||
SUB(Lib, Usbd) \
|
||||
SUB(Lib, Ajm) \
|
||||
@ -120,6 +128,12 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
SUB(Lib, SharePlay) \
|
||||
SUB(Lib, Fiber) \
|
||||
SUB(Lib, Vdec2) \
|
||||
SUB(Lib, Videodec) \
|
||||
SUB(Lib, RazorCpu) \
|
||||
SUB(Lib, Mouse) \
|
||||
SUB(Lib, WebBrowserDialog) \
|
||||
SUB(Lib, NpParty) \
|
||||
SUB(Lib, Zlib) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Vulkan) \
|
||||
|
@ -35,6 +35,7 @@ enum class Class : u8 {
|
||||
Common_Memory, ///< Memory mapping and management functions
|
||||
Core, ///< LLE emulation core
|
||||
Core_Linker, ///< The module linker
|
||||
Core_Devices, ///< Devices emulation
|
||||
Config, ///< Emulator configuration (including commandline)
|
||||
Debug, ///< Debugging tools
|
||||
Kernel, ///< The HLE implementation of the PS4 kernel.
|
||||
@ -56,23 +57,30 @@ enum class Class : u8 {
|
||||
Lib_MsgDlg, ///< The LibSceMsgDialog implementation.
|
||||
Lib_AudioOut, ///< The LibSceAudioOut implementation.
|
||||
Lib_AudioIn, ///< The LibSceAudioIn implementation.
|
||||
Lib_Move, ///< The LibSceMove implementation.
|
||||
Lib_Net, ///< The LibSceNet implementation.
|
||||
Lib_NetCtl, ///< The LibSecNetCtl implementation.
|
||||
Lib_NetCtl, ///< The LibSceNetCtl implementation.
|
||||
Lib_SaveData, ///< The LibSceSaveData implementation.
|
||||
Lib_SaveDataDialog, ///< The LibSceSaveDataDialog implementation.
|
||||
Lib_Ssl, ///< The LibSceSsl implementation.
|
||||
Lib_Ssl2, ///< The LibSceSsl2 implementation.
|
||||
Lib_Http, ///< The LibSceHttp implementation.
|
||||
Lib_Http2, ///< The LibSceHttp2 implementation.
|
||||
Lib_SysModule, ///< The LibSceSysModule implementation
|
||||
Lib_NpCommon, ///< The LibSceNpCommon implementation
|
||||
Lib_NpManager, ///< The LibSceNpManager implementation
|
||||
Lib_NpScore, ///< The LibSceNpScore implementation
|
||||
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
||||
Lib_NpWebApi, ///< The LibSceWebApi implementation
|
||||
Lib_Screenshot, ///< The LibSceScreenshot implementation
|
||||
Lib_LibCInternal, ///< The LibCInternal implementation.
|
||||
Lib_AppContent, ///< The LibSceAppContent implementation.
|
||||
Lib_Rtc, ///< The LibSceRtc implementation.
|
||||
Lib_DiscMap, ///< The LibSceDiscMap implementation.
|
||||
Lib_Png, ///< The LibScePng implementation.
|
||||
Lib_Jpeg, ///< The LibSceJpeg implementation.
|
||||
Lib_PlayGo, ///< The LibScePlayGo implementation.
|
||||
Lib_PlayGoDialog, ///< The LibScePlayGoDialog implementation.
|
||||
Lib_Random, ///< The libSceRandom implementation.
|
||||
Lib_Usbd, ///< The LibSceUsbd implementation.
|
||||
Lib_Ajm, ///< The LibSceAjm implementation.
|
||||
@ -87,6 +95,12 @@ enum class Class : u8 {
|
||||
Lib_SharePlay, ///< The LibSceSharePlay implemenation
|
||||
Lib_Fiber, ///< The LibSceFiber implementation.
|
||||
Lib_Vdec2, ///< The LibSceVideodec2 implementation.
|
||||
Lib_Videodec, ///< The LibSceVideodec implementation.
|
||||
Lib_RazorCpu, ///< The LibRazorCpu implementation.
|
||||
Lib_Mouse, ///< The LibSceMouse implementation
|
||||
Lib_WebBrowserDialog, ///< The LibSceWebBrowserDialog implementation
|
||||
Lib_NpParty, ///< The LibSceNpParty implementation
|
||||
Lib_Zlib, ///< The LibSceZlib implementation.
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Video Core
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <string>
|
||||
#include <pugixml.hpp>
|
||||
#ifdef ENABLE_QT_GUI
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@ -28,7 +29,7 @@ std::string g_game_serial;
|
||||
std::string patchFile;
|
||||
std::vector<patchInfo> pending_patches;
|
||||
|
||||
std::string toHex(unsigned long long value, size_t byteSize) {
|
||||
std::string toHex(u64 value, size_t byteSize) {
|
||||
std::stringstream ss;
|
||||
ss << std::hex << std::setfill('0') << std::setw(byteSize * 2) << value;
|
||||
return ss.str();
|
||||
@ -38,16 +39,16 @@ std::string convertValueToHex(const std::string type, const std::string valueStr
|
||||
std::string result;
|
||||
|
||||
if (type == "byte") {
|
||||
unsigned int value = std::stoul(valueStr, nullptr, 16);
|
||||
const u32 value = std::stoul(valueStr, nullptr, 16);
|
||||
result = toHex(value, 1);
|
||||
} else if (type == "bytes16") {
|
||||
unsigned int value = std::stoul(valueStr, nullptr, 16);
|
||||
const u32 value = std::stoul(valueStr, nullptr, 16);
|
||||
result = toHex(value, 2);
|
||||
} else if (type == "bytes32") {
|
||||
unsigned long value = std::stoul(valueStr, nullptr, 16);
|
||||
const u32 value = std::stoul(valueStr, nullptr, 16);
|
||||
result = toHex(value, 4);
|
||||
} else if (type == "bytes64") {
|
||||
unsigned long long value = std::stoull(valueStr, nullptr, 16);
|
||||
const u64 value = std::stoull(valueStr, nullptr, 16);
|
||||
result = toHex(value, 8);
|
||||
} else if (type == "float32") {
|
||||
union {
|
||||
@ -189,14 +190,16 @@ void OnGameLoaded() {
|
||||
// We use the QT headers for the xml and json parsing, this define is only true on QT builds
|
||||
QString patchDir;
|
||||
Common::FS::PathToQString(patchDir, Common::FS::GetUserPath(Common::FS::PathType::PatchesDir));
|
||||
QString repositories[] = {"GoldHEN", "shadPS4"};
|
||||
QDir dir(patchDir);
|
||||
QStringList folders = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
for (const QString& repository : repositories) {
|
||||
QString filesJsonPath = patchDir + "/" + repository + "/files.json";
|
||||
for (const QString& folder : folders) {
|
||||
QString filesJsonPath = patchDir + "/" + folder + "/files.json";
|
||||
|
||||
QFile jsonFile(filesJsonPath);
|
||||
if (!jsonFile.open(QIODevice::ReadOnly)) {
|
||||
LOG_ERROR(Loader, "Unable to open files.json for reading.");
|
||||
LOG_ERROR(Loader, "Unable to open files.json for reading in repository {}",
|
||||
folder.toStdString());
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -220,11 +223,12 @@ void OnGameLoaded() {
|
||||
}
|
||||
|
||||
if (selectedFileName.isEmpty()) {
|
||||
LOG_ERROR(Loader, "No patch file found for the current serial.");
|
||||
LOG_ERROR(Loader, "No patch file found for the current serial in repository {}",
|
||||
folder.toStdString());
|
||||
continue;
|
||||
}
|
||||
|
||||
QString filePath = patchDir + "/" + repository + "/" + selectedFileName;
|
||||
QString filePath = patchDir + "/" + folder + "/" + selectedFileName;
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
LOG_ERROR(Loader, "Unable to open the file for reading.");
|
||||
|
@ -4,11 +4,6 @@
|
||||
#include "common/native_clock.h"
|
||||
#include "common/rdtsc.h"
|
||||
#include "common/uint128.h"
|
||||
#ifdef _WIN64
|
||||
#include <pthread_time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
namespace Common {
|
||||
|
||||
@ -34,10 +29,4 @@ u64 NativeClock::GetUptime() const {
|
||||
return FencedRDTSC();
|
||||
}
|
||||
|
||||
u64 NativeClock::GetProcessTimeUS() const {
|
||||
timespec ret;
|
||||
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ret);
|
||||
return ret.tv_nsec / 1000 + ret.tv_sec * 1000000;
|
||||
}
|
||||
|
||||
} // namespace Common
|
||||
|
@ -20,7 +20,6 @@ public:
|
||||
u64 GetTimeUS(u64 base_ptc = 0) const;
|
||||
u64 GetTimeMS(u64 base_ptc = 0) const;
|
||||
u64 GetUptime() const;
|
||||
u64 GetProcessTimeUS() const;
|
||||
|
||||
private:
|
||||
u64 rdtsc_frequency;
|
||||
|
@ -1,24 +1,30 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "ntapi.h"
|
||||
|
||||
NtDelayExecution_t NtDelayExecution = nullptr;
|
||||
NtSetInformationFile_t NtSetInformationFile = nullptr;
|
||||
|
||||
namespace Common::NtApi {
|
||||
|
||||
void Initialize() {
|
||||
HMODULE nt_handle = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
// http://stackoverflow.com/a/31411628/4725495
|
||||
NtDelayExecution = (NtDelayExecution_t)GetProcAddress(nt_handle, "NtDelayExecution");
|
||||
NtSetInformationFile =
|
||||
(NtSetInformationFile_t)GetProcAddress(nt_handle, "NtSetInformationFile");
|
||||
}
|
||||
|
||||
} // namespace Common::NtApi
|
||||
|
||||
#endif
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "ntapi.h"
|
||||
|
||||
NtClose_t NtClose = nullptr;
|
||||
NtSetInformationFile_t NtSetInformationFile = nullptr;
|
||||
NtCreateThread_t NtCreateThread = nullptr;
|
||||
NtTerminateThread_t NtTerminateThread = nullptr;
|
||||
NtQueueApcThreadEx_t NtQueueApcThreadEx = nullptr;
|
||||
|
||||
namespace Common::NtApi {
|
||||
|
||||
void Initialize() {
|
||||
HMODULE nt_handle = GetModuleHandleA("ntdll.dll");
|
||||
|
||||
// http://stackoverflow.com/a/31411628/4725495
|
||||
NtClose = (NtClose_t)GetProcAddress(nt_handle, "NtClose");
|
||||
NtSetInformationFile =
|
||||
(NtSetInformationFile_t)GetProcAddress(nt_handle, "NtSetInformationFile");
|
||||
NtCreateThread = (NtCreateThread_t)GetProcAddress(nt_handle, "NtCreateThread");
|
||||
NtTerminateThread = (NtTerminateThread_t)GetProcAddress(nt_handle, "NtTerminateThread");
|
||||
NtQueueApcThreadEx = (NtQueueApcThreadEx_t)GetProcAddress(nt_handle, "NtQueueApcThreadEx");
|
||||
}
|
||||
|
||||
} // namespace Common::NtApi
|
||||
|
||||
#endif
|
||||
|
@ -1,124 +1,554 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include "common/types.h"
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
FileDirectoryInformation = 1,
|
||||
FileFullDirectoryInformation = 2,
|
||||
FileBothDirectoryInformation = 3,
|
||||
FileBasicInformation = 4,
|
||||
FileStandardInformation = 5,
|
||||
FileInternalInformation = 6,
|
||||
FileEaInformation = 7,
|
||||
FileAccessInformation = 8,
|
||||
FileNameInformation = 9,
|
||||
FileRenameInformation = 10,
|
||||
FileLinkInformation = 11,
|
||||
FileNamesInformation = 12,
|
||||
FileDispositionInformation = 13,
|
||||
FilePositionInformation = 14,
|
||||
FileFullEaInformation = 15,
|
||||
FileModeInformation = 16,
|
||||
FileAlignmentInformation = 17,
|
||||
FileAllInformation = 18,
|
||||
FileAllocationInformation = 19,
|
||||
FileEndOfFileInformation = 20,
|
||||
FileAlternateNameInformation = 21,
|
||||
FileStreamInformation = 22,
|
||||
FilePipeInformation = 23,
|
||||
FilePipeLocalInformation = 24,
|
||||
FilePipeRemoteInformation = 25,
|
||||
FileMailslotQueryInformation = 26,
|
||||
FileMailslotSetInformation = 27,
|
||||
FileCompressionInformation = 28,
|
||||
FileObjectIdInformation = 29,
|
||||
FileCompletionInformation = 30,
|
||||
FileMoveClusterInformation = 31,
|
||||
FileQuotaInformation = 32,
|
||||
FileReparsePointInformation = 33,
|
||||
FileNetworkOpenInformation = 34,
|
||||
FileAttributeTagInformation = 35,
|
||||
FileTrackingInformation = 36,
|
||||
FileIdBothDirectoryInformation = 37,
|
||||
FileIdFullDirectoryInformation = 38,
|
||||
FileValidDataLengthInformation = 39,
|
||||
FileShortNameInformation = 40,
|
||||
FileIoCompletionNotificationInformation = 41,
|
||||
FileIoStatusBlockRangeInformation = 42,
|
||||
FileIoPriorityHintInformation = 43,
|
||||
FileSfioReserveInformation = 44,
|
||||
FileSfioVolumeInformation = 45,
|
||||
FileHardLinkInformation = 46,
|
||||
FileProcessIdsUsingFileInformation = 47,
|
||||
FileNormalizedNameInformation = 48,
|
||||
FileNetworkPhysicalNameInformation = 49,
|
||||
FileIdGlobalTxDirectoryInformation = 50,
|
||||
FileIsRemoteDeviceInformation = 51,
|
||||
FileUnusedInformation = 52,
|
||||
FileNumaNodeInformation = 53,
|
||||
FileStandardLinkInformation = 54,
|
||||
FileRemoteProtocolInformation = 55,
|
||||
FileRenameInformationBypassAccessCheck = 56,
|
||||
FileLinkInformationBypassAccessCheck = 57,
|
||||
FileVolumeNameInformation = 58,
|
||||
FileIdInformation = 59,
|
||||
FileIdExtdDirectoryInformation = 60,
|
||||
FileReplaceCompletionInformation = 61,
|
||||
FileHardLinkFullIdInformation = 62,
|
||||
FileIdExtdBothDirectoryInformation = 63,
|
||||
FileDispositionInformationEx = 64,
|
||||
FileRenameInformationEx = 65,
|
||||
FileRenameInformationExBypassAccessCheck = 66,
|
||||
FileDesiredStorageClassInformation = 67,
|
||||
FileStatInformation = 68,
|
||||
FileMemoryPartitionInformation = 69,
|
||||
FileStatLxInformation = 70,
|
||||
FileCaseSensitiveInformation = 71,
|
||||
FileLinkInformationEx = 72,
|
||||
FileLinkInformationExBypassAccessCheck = 73,
|
||||
FileStorageReserveIdInformation = 74,
|
||||
FileCaseSensitiveInformationForceAccessCheck = 75,
|
||||
FileKnownFolderInformation = 76,
|
||||
FileStatBasicInformation = 77,
|
||||
FileId64ExtdDirectoryInformation = 78,
|
||||
FileId64ExtdBothDirectoryInformation = 79,
|
||||
FileIdAllExtdDirectoryInformation = 80,
|
||||
FileIdAllExtdBothDirectoryInformation = 81,
|
||||
FileStreamReservationInformation,
|
||||
FileMupProviderInfo,
|
||||
FileMaximumInformation
|
||||
} FILE_INFORMATION_CLASS,
|
||||
*PFILE_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
u32 Status;
|
||||
PVOID Pointer;
|
||||
};
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
typedef struct _FILE_DISPOSITION_INFORMATION {
|
||||
BOOLEAN DeleteFile;
|
||||
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
|
||||
|
||||
typedef u32(__stdcall* NtDelayExecution_t)(BOOL Alertable, PLARGE_INTEGER DelayInterval);
|
||||
|
||||
typedef u32(__stdcall* NtSetInformationFile_t)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID FileInformation, ULONG Length,
|
||||
FILE_INFORMATION_CLASS FileInformationClass);
|
||||
|
||||
extern NtDelayExecution_t NtDelayExecution;
|
||||
extern NtSetInformationFile_t NtSetInformationFile;
|
||||
|
||||
namespace Common::NtApi {
|
||||
void Initialize();
|
||||
}
|
||||
|
||||
#endif
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include "common/types.h"
|
||||
|
||||
typedef enum _FILE_INFORMATION_CLASS {
|
||||
FileDirectoryInformation = 1,
|
||||
FileFullDirectoryInformation = 2,
|
||||
FileBothDirectoryInformation = 3,
|
||||
FileBasicInformation = 4,
|
||||
FileStandardInformation = 5,
|
||||
FileInternalInformation = 6,
|
||||
FileEaInformation = 7,
|
||||
FileAccessInformation = 8,
|
||||
FileNameInformation = 9,
|
||||
FileRenameInformation = 10,
|
||||
FileLinkInformation = 11,
|
||||
FileNamesInformation = 12,
|
||||
FileDispositionInformation = 13,
|
||||
FilePositionInformation = 14,
|
||||
FileFullEaInformation = 15,
|
||||
FileModeInformation = 16,
|
||||
FileAlignmentInformation = 17,
|
||||
FileAllInformation = 18,
|
||||
FileAllocationInformation = 19,
|
||||
FileEndOfFileInformation = 20,
|
||||
FileAlternateNameInformation = 21,
|
||||
FileStreamInformation = 22,
|
||||
FilePipeInformation = 23,
|
||||
FilePipeLocalInformation = 24,
|
||||
FilePipeRemoteInformation = 25,
|
||||
FileMailslotQueryInformation = 26,
|
||||
FileMailslotSetInformation = 27,
|
||||
FileCompressionInformation = 28,
|
||||
FileObjectIdInformation = 29,
|
||||
FileCompletionInformation = 30,
|
||||
FileMoveClusterInformation = 31,
|
||||
FileQuotaInformation = 32,
|
||||
FileReparsePointInformation = 33,
|
||||
FileNetworkOpenInformation = 34,
|
||||
FileAttributeTagInformation = 35,
|
||||
FileTrackingInformation = 36,
|
||||
FileIdBothDirectoryInformation = 37,
|
||||
FileIdFullDirectoryInformation = 38,
|
||||
FileValidDataLengthInformation = 39,
|
||||
FileShortNameInformation = 40,
|
||||
FileIoCompletionNotificationInformation = 41,
|
||||
FileIoStatusBlockRangeInformation = 42,
|
||||
FileIoPriorityHintInformation = 43,
|
||||
FileSfioReserveInformation = 44,
|
||||
FileSfioVolumeInformation = 45,
|
||||
FileHardLinkInformation = 46,
|
||||
FileProcessIdsUsingFileInformation = 47,
|
||||
FileNormalizedNameInformation = 48,
|
||||
FileNetworkPhysicalNameInformation = 49,
|
||||
FileIdGlobalTxDirectoryInformation = 50,
|
||||
FileIsRemoteDeviceInformation = 51,
|
||||
FileUnusedInformation = 52,
|
||||
FileNumaNodeInformation = 53,
|
||||
FileStandardLinkInformation = 54,
|
||||
FileRemoteProtocolInformation = 55,
|
||||
FileRenameInformationBypassAccessCheck = 56,
|
||||
FileLinkInformationBypassAccessCheck = 57,
|
||||
FileVolumeNameInformation = 58,
|
||||
FileIdInformation = 59,
|
||||
FileIdExtdDirectoryInformation = 60,
|
||||
FileReplaceCompletionInformation = 61,
|
||||
FileHardLinkFullIdInformation = 62,
|
||||
FileIdExtdBothDirectoryInformation = 63,
|
||||
FileDispositionInformationEx = 64,
|
||||
FileRenameInformationEx = 65,
|
||||
FileRenameInformationExBypassAccessCheck = 66,
|
||||
FileDesiredStorageClassInformation = 67,
|
||||
FileStatInformation = 68,
|
||||
FileMemoryPartitionInformation = 69,
|
||||
FileStatLxInformation = 70,
|
||||
FileCaseSensitiveInformation = 71,
|
||||
FileLinkInformationEx = 72,
|
||||
FileLinkInformationExBypassAccessCheck = 73,
|
||||
FileStorageReserveIdInformation = 74,
|
||||
FileCaseSensitiveInformationForceAccessCheck = 75,
|
||||
FileKnownFolderInformation = 76,
|
||||
FileStatBasicInformation = 77,
|
||||
FileId64ExtdDirectoryInformation = 78,
|
||||
FileId64ExtdBothDirectoryInformation = 79,
|
||||
FileIdAllExtdDirectoryInformation = 80,
|
||||
FileIdAllExtdBothDirectoryInformation = 81,
|
||||
FileStreamReservationInformation,
|
||||
FileMupProviderInfo,
|
||||
FileMaximumInformation
|
||||
} FILE_INFORMATION_CLASS,
|
||||
*PFILE_INFORMATION_CLASS;
|
||||
|
||||
typedef struct _IO_STATUS_BLOCK {
|
||||
union {
|
||||
u32 Status;
|
||||
PVOID Pointer;
|
||||
};
|
||||
ULONG_PTR Information;
|
||||
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
|
||||
|
||||
typedef struct _FILE_DISPOSITION_INFORMATION {
|
||||
BOOLEAN DeleteFile;
|
||||
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
|
||||
|
||||
typedef struct _UNICODE_STRING {
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWCH Buffer;
|
||||
} UNICODE_STRING, *PUNICODE_STRING;
|
||||
|
||||
typedef const UNICODE_STRING* PCUNICODE_STRING;
|
||||
|
||||
typedef struct _OBJECT_ATTRIBUTES {
|
||||
ULONG Length;
|
||||
HANDLE RootDirectory;
|
||||
PCUNICODE_STRING ObjectName;
|
||||
ULONG Attributes;
|
||||
PVOID SecurityDescriptor; // PSECURITY_DESCRIPTOR;
|
||||
PVOID SecurityQualityOfService; // PSECURITY_QUALITY_OF_SERVICE
|
||||
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
|
||||
|
||||
typedef const OBJECT_ATTRIBUTES* PCOBJECT_ATTRIBUTES;
|
||||
|
||||
typedef struct _CLIENT_ID {
|
||||
HANDLE UniqueProcess;
|
||||
HANDLE UniqueThread;
|
||||
} CLIENT_ID, *PCLIENT_ID;
|
||||
|
||||
typedef struct _INITIAL_TEB {
|
||||
struct {
|
||||
PVOID OldStackBase;
|
||||
PVOID OldStackLimit;
|
||||
} OldInitialTeb;
|
||||
PVOID StackBase;
|
||||
PVOID StackLimit;
|
||||
PVOID StackAllocationBase;
|
||||
} INITIAL_TEB, *PINITIAL_TEB;
|
||||
|
||||
typedef struct _PEB_LDR_DATA {
|
||||
ULONG Length;
|
||||
BOOLEAN Initialized;
|
||||
PVOID SsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID EntryInProgress;
|
||||
BOOLEAN ShutdownInProgress;
|
||||
HANDLE ShutdownThreadId;
|
||||
} PEB_LDR_DATA, *PPEB_LDR_DATA;
|
||||
|
||||
typedef struct _CURDIR {
|
||||
UNICODE_STRING DosPath;
|
||||
PVOID Handle;
|
||||
} CURDIR, *PCURDIR;
|
||||
|
||||
typedef struct RTL_DRIVE_LETTER_CURDIR {
|
||||
USHORT Flags;
|
||||
USHORT Length;
|
||||
ULONG TimeStamp;
|
||||
UNICODE_STRING DosPath;
|
||||
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
|
||||
|
||||
typedef struct _RTL_USER_PROCESS_PARAMETERS {
|
||||
ULONG AllocationSize;
|
||||
ULONG Size;
|
||||
ULONG Flags;
|
||||
ULONG DebugFlags;
|
||||
HANDLE ConsoleHandle;
|
||||
ULONG ConsoleFlags;
|
||||
HANDLE hStdInput;
|
||||
HANDLE hStdOutput;
|
||||
HANDLE hStdError;
|
||||
CURDIR CurrentDirectory;
|
||||
UNICODE_STRING DllPath;
|
||||
UNICODE_STRING ImagePathName;
|
||||
UNICODE_STRING CommandLine;
|
||||
PWSTR Environment;
|
||||
ULONG dwX;
|
||||
ULONG dwY;
|
||||
ULONG dwXSize;
|
||||
ULONG dwYSize;
|
||||
ULONG dwXCountChars;
|
||||
ULONG dwYCountChars;
|
||||
ULONG dwFillAttribute;
|
||||
ULONG dwFlags;
|
||||
ULONG wShowWindow;
|
||||
UNICODE_STRING WindowTitle;
|
||||
UNICODE_STRING Desktop;
|
||||
UNICODE_STRING ShellInfo;
|
||||
UNICODE_STRING RuntimeInfo;
|
||||
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
|
||||
ULONG_PTR EnvironmentSize;
|
||||
ULONG_PTR EnvironmentVersion;
|
||||
PVOID PackageDependencyData;
|
||||
ULONG ProcessGroupId;
|
||||
ULONG LoaderThreads;
|
||||
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
|
||||
|
||||
typedef struct tagRTL_BITMAP {
|
||||
ULONG SizeOfBitMap;
|
||||
PULONG Buffer;
|
||||
} RTL_BITMAP, *PRTL_BITMAP;
|
||||
|
||||
typedef struct {
|
||||
UINT next;
|
||||
UINT id;
|
||||
ULONGLONG addr;
|
||||
ULONGLONG size;
|
||||
UINT args[4];
|
||||
} CROSS_PROCESS_WORK_ENTRY;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
UINT first;
|
||||
UINT counter;
|
||||
};
|
||||
volatile LONGLONG hdr;
|
||||
} CROSS_PROCESS_WORK_HDR;
|
||||
|
||||
typedef struct {
|
||||
CROSS_PROCESS_WORK_HDR free_list;
|
||||
CROSS_PROCESS_WORK_HDR work_list;
|
||||
ULONGLONG unknown[4];
|
||||
CROSS_PROCESS_WORK_ENTRY entries[1];
|
||||
} CROSS_PROCESS_WORK_LIST;
|
||||
|
||||
typedef struct _CHPEV2_PROCESS_INFO {
|
||||
ULONG Wow64ExecuteFlags; /* 000 */
|
||||
USHORT NativeMachineType; /* 004 */
|
||||
USHORT EmulatedMachineType; /* 006 */
|
||||
HANDLE SectionHandle; /* 008 */
|
||||
CROSS_PROCESS_WORK_LIST* CrossProcessWorkList; /* 010 */
|
||||
void* unknown; /* 018 */
|
||||
} CHPEV2_PROCESS_INFO, *PCHPEV2_PROCESS_INFO;
|
||||
|
||||
typedef u64(__stdcall* KERNEL_CALLBACK_PROC)(void*, ULONG);
|
||||
|
||||
typedef struct _PEB { /* win32/win64 */
|
||||
BOOLEAN InheritedAddressSpace; /* 000/000 */
|
||||
BOOLEAN ReadImageFileExecOptions; /* 001/001 */
|
||||
BOOLEAN BeingDebugged; /* 002/002 */
|
||||
UCHAR ImageUsedLargePages : 1; /* 003/003 */
|
||||
UCHAR IsProtectedProcess : 1;
|
||||
UCHAR IsImageDynamicallyRelocated : 1;
|
||||
UCHAR SkipPatchingUser32Forwarders : 1;
|
||||
UCHAR IsPackagedProcess : 1;
|
||||
UCHAR IsAppContainer : 1;
|
||||
UCHAR IsProtectedProcessLight : 1;
|
||||
UCHAR IsLongPathAwareProcess : 1;
|
||||
HANDLE Mutant; /* 004/008 */
|
||||
HMODULE ImageBaseAddress; /* 008/010 */
|
||||
PPEB_LDR_DATA LdrData; /* 00c/018 */
|
||||
RTL_USER_PROCESS_PARAMETERS* ProcessParameters; /* 010/020 */
|
||||
PVOID SubSystemData; /* 014/028 */
|
||||
HANDLE ProcessHeap; /* 018/030 */
|
||||
PRTL_CRITICAL_SECTION FastPebLock; /* 01c/038 */
|
||||
PVOID AtlThunkSListPtr; /* 020/040 */
|
||||
PVOID IFEOKey; /* 024/048 */
|
||||
ULONG ProcessInJob : 1; /* 028/050 */
|
||||
ULONG ProcessInitializing : 1;
|
||||
ULONG ProcessUsingVEH : 1;
|
||||
ULONG ProcessUsingVCH : 1;
|
||||
ULONG ProcessUsingFTH : 1;
|
||||
ULONG ProcessPreviouslyThrottled : 1;
|
||||
ULONG ProcessCurrentlyThrottled : 1;
|
||||
ULONG ProcessImagesHotPatched : 1;
|
||||
ULONG ReservedBits0 : 24;
|
||||
KERNEL_CALLBACK_PROC* KernelCallbackTable; /* 02c/058 */
|
||||
ULONG Reserved; /* 030/060 */
|
||||
ULONG AtlThunkSListPtr32; /* 034/064 */
|
||||
PVOID ApiSetMap; /* 038/068 */
|
||||
ULONG TlsExpansionCounter; /* 03c/070 */
|
||||
PRTL_BITMAP TlsBitmap; /* 040/078 */
|
||||
ULONG TlsBitmapBits[2]; /* 044/080 */
|
||||
PVOID ReadOnlySharedMemoryBase; /* 04c/088 */
|
||||
PVOID SharedData; /* 050/090 */
|
||||
PVOID* ReadOnlyStaticServerData; /* 054/098 */
|
||||
PVOID AnsiCodePageData; /* 058/0a0 */
|
||||
PVOID OemCodePageData; /* 05c/0a8 */
|
||||
PVOID UnicodeCaseTableData; /* 060/0b0 */
|
||||
ULONG NumberOfProcessors; /* 064/0b8 */
|
||||
ULONG NtGlobalFlag; /* 068/0bc */
|
||||
LARGE_INTEGER CriticalSectionTimeout; /* 070/0c0 */
|
||||
SIZE_T HeapSegmentReserve; /* 078/0c8 */
|
||||
SIZE_T HeapSegmentCommit; /* 07c/0d0 */
|
||||
SIZE_T HeapDeCommitTotalFreeThreshold; /* 080/0d8 */
|
||||
SIZE_T HeapDeCommitFreeBlockThreshold; /* 084/0e0 */
|
||||
ULONG NumberOfHeaps; /* 088/0e8 */
|
||||
ULONG MaximumNumberOfHeaps; /* 08c/0ec */
|
||||
PVOID* ProcessHeaps; /* 090/0f0 */
|
||||
PVOID GdiSharedHandleTable; /* 094/0f8 */
|
||||
PVOID ProcessStarterHelper; /* 098/100 */
|
||||
PVOID GdiDCAttributeList; /* 09c/108 */
|
||||
PVOID LoaderLock; /* 0a0/110 */
|
||||
ULONG OSMajorVersion; /* 0a4/118 */
|
||||
ULONG OSMinorVersion; /* 0a8/11c */
|
||||
ULONG OSBuildNumber; /* 0ac/120 */
|
||||
ULONG OSPlatformId; /* 0b0/124 */
|
||||
ULONG ImageSubSystem; /* 0b4/128 */
|
||||
ULONG ImageSubSystemMajorVersion; /* 0b8/12c */
|
||||
ULONG ImageSubSystemMinorVersion; /* 0bc/130 */
|
||||
KAFFINITY ActiveProcessAffinityMask; /* 0c0/138 */
|
||||
#ifdef _WIN64
|
||||
ULONG GdiHandleBuffer[60]; /* /140 */
|
||||
#else
|
||||
ULONG GdiHandleBuffer[34]; /* 0c4/ */
|
||||
#endif
|
||||
PVOID PostProcessInitRoutine; /* 14c/230 */
|
||||
PRTL_BITMAP TlsExpansionBitmap; /* 150/238 */
|
||||
ULONG TlsExpansionBitmapBits[32]; /* 154/240 */
|
||||
ULONG SessionId; /* 1d4/2c0 */
|
||||
ULARGE_INTEGER AppCompatFlags; /* 1d8/2c8 */
|
||||
ULARGE_INTEGER AppCompatFlagsUser; /* 1e0/2d0 */
|
||||
PVOID ShimData; /* 1e8/2d8 */
|
||||
PVOID AppCompatInfo; /* 1ec/2e0 */
|
||||
UNICODE_STRING CSDVersion; /* 1f0/2e8 */
|
||||
PVOID ActivationContextData; /* 1f8/2f8 */
|
||||
PVOID ProcessAssemblyStorageMap; /* 1fc/300 */
|
||||
PVOID SystemDefaultActivationData; /* 200/308 */
|
||||
PVOID SystemAssemblyStorageMap; /* 204/310 */
|
||||
SIZE_T MinimumStackCommit; /* 208/318 */
|
||||
PVOID* FlsCallback; /* 20c/320 */
|
||||
LIST_ENTRY FlsListHead; /* 210/328 */
|
||||
union {
|
||||
PRTL_BITMAP FlsBitmap; /* 218/338 */
|
||||
#ifdef _WIN64
|
||||
CHPEV2_PROCESS_INFO* ChpeV2ProcessInfo; /* /338 */
|
||||
#endif
|
||||
};
|
||||
ULONG FlsBitmapBits[4]; /* 21c/340 */
|
||||
ULONG FlsHighIndex; /* 22c/350 */
|
||||
PVOID WerRegistrationData; /* 230/358 */
|
||||
PVOID WerShipAssertPtr; /* 234/360 */
|
||||
PVOID EcCodeBitMap; /* 238/368 */
|
||||
PVOID pImageHeaderHash; /* 23c/370 */
|
||||
ULONG HeapTracingEnabled : 1; /* 240/378 */
|
||||
ULONG CritSecTracingEnabled : 1;
|
||||
ULONG LibLoaderTracingEnabled : 1;
|
||||
ULONG SpareTracingBits : 29;
|
||||
ULONGLONG CsrServerReadOnlySharedMemoryBase; /* 248/380 */
|
||||
ULONG TppWorkerpListLock; /* 250/388 */
|
||||
LIST_ENTRY TppWorkerpList; /* 254/390 */
|
||||
PVOID WaitOnAddressHashTable[0x80]; /* 25c/3a0 */
|
||||
PVOID TelemetryCoverageHeader; /* 45c/7a0 */
|
||||
ULONG CloudFileFlags; /* 460/7a8 */
|
||||
ULONG CloudFileDiagFlags; /* 464/7ac */
|
||||
CHAR PlaceholderCompatibilityMode; /* 468/7b0 */
|
||||
CHAR PlaceholderCompatibilityModeReserved[7]; /* 469/7b1 */
|
||||
PVOID LeapSecondData; /* 470/7b8 */
|
||||
ULONG LeapSecondFlags; /* 474/7c0 */
|
||||
ULONG NtGlobalFlag2; /* 478/7c4 */
|
||||
} PEB, *PPEB;
|
||||
|
||||
typedef struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME {
|
||||
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* Previous;
|
||||
struct _ACTIVATION_CONTEXT* ActivationContext;
|
||||
ULONG Flags;
|
||||
} RTL_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_ACTIVATION_CONTEXT_STACK_FRAME;
|
||||
|
||||
typedef struct _ACTIVATION_CONTEXT_STACK {
|
||||
RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame;
|
||||
LIST_ENTRY FrameListCache;
|
||||
ULONG Flags;
|
||||
ULONG NextCookieSequenceNumber;
|
||||
ULONG_PTR StackId;
|
||||
} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK;
|
||||
|
||||
typedef struct _GDI_TEB_BATCH {
|
||||
ULONG Offset;
|
||||
HANDLE HDC;
|
||||
ULONG Buffer[0x136];
|
||||
} GDI_TEB_BATCH;
|
||||
|
||||
typedef struct _TEB_ACTIVE_FRAME_CONTEXT {
|
||||
ULONG Flags;
|
||||
const char* FrameName;
|
||||
} TEB_ACTIVE_FRAME_CONTEXT, *PTEB_ACTIVE_FRAME_CONTEXT;
|
||||
|
||||
typedef struct _TEB_ACTIVE_FRAME {
|
||||
ULONG Flags;
|
||||
struct _TEB_ACTIVE_FRAME* Previous;
|
||||
TEB_ACTIVE_FRAME_CONTEXT* Context;
|
||||
} TEB_ACTIVE_FRAME, *PTEB_ACTIVE_FRAME;
|
||||
|
||||
typedef struct _TEB { /* win32/win64 */
|
||||
NT_TIB Tib; /* 000/0000 */
|
||||
PVOID EnvironmentPointer; /* 01c/0038 */
|
||||
CLIENT_ID ClientId; /* 020/0040 */
|
||||
PVOID ActiveRpcHandle; /* 028/0050 */
|
||||
PVOID ThreadLocalStoragePointer; /* 02c/0058 */
|
||||
PPEB Peb; /* 030/0060 */
|
||||
ULONG LastErrorValue; /* 034/0068 */
|
||||
ULONG CountOfOwnedCriticalSections; /* 038/006c */
|
||||
PVOID CsrClientThread; /* 03c/0070 */
|
||||
PVOID Win32ThreadInfo; /* 040/0078 */
|
||||
ULONG User32Reserved[26]; /* 044/0080 */
|
||||
ULONG UserReserved[5]; /* 0ac/00e8 */
|
||||
PVOID WOW32Reserved; /* 0c0/0100 */
|
||||
ULONG CurrentLocale; /* 0c4/0108 */
|
||||
ULONG FpSoftwareStatusRegister; /* 0c8/010c */
|
||||
PVOID ReservedForDebuggerInstrumentation[16]; /* 0cc/0110 */
|
||||
#ifdef _WIN64
|
||||
PVOID SystemReserved1[30]; /* /0190 */
|
||||
#else
|
||||
PVOID SystemReserved1[26]; /* 10c/ */
|
||||
#endif
|
||||
char PlaceholderCompatibilityMode; /* 174/0280 */
|
||||
BOOLEAN PlaceholderHydrationAlwaysExplicit; /* 175/0281 */
|
||||
char PlaceholderReserved[10]; /* 176/0282 */
|
||||
DWORD ProxiedProcessId; /* 180/028c */
|
||||
ACTIVATION_CONTEXT_STACK ActivationContextStack; /* 184/0290 */
|
||||
UCHAR WorkingOnBehalfOfTicket[8]; /* 19c/02b8 */
|
||||
LONG ExceptionCode; /* 1a4/02c0 */
|
||||
ACTIVATION_CONTEXT_STACK* ActivationContextStackPointer; /* 1a8/02c8 */
|
||||
ULONG_PTR InstrumentationCallbackSp; /* 1ac/02d0 */
|
||||
ULONG_PTR InstrumentationCallbackPreviousPc; /* 1b0/02d8 */
|
||||
ULONG_PTR InstrumentationCallbackPreviousSp; /* 1b4/02e0 */
|
||||
#ifdef _WIN64
|
||||
ULONG TxFsContext; /* /02e8 */
|
||||
BOOLEAN InstrumentationCallbackDisabled; /* /02ec */
|
||||
BOOLEAN UnalignedLoadStoreExceptions; /* /02ed */
|
||||
#else
|
||||
BOOLEAN InstrumentationCallbackDisabled; /* 1b8/ */
|
||||
BYTE SpareBytes1[23]; /* 1b9/ */
|
||||
ULONG TxFsContext; /* 1d0/ */
|
||||
#endif
|
||||
GDI_TEB_BATCH GdiTebBatch; /* 1d4/02f0 */
|
||||
CLIENT_ID RealClientId; /* 6b4/07d8 */
|
||||
HANDLE GdiCachedProcessHandle; /* 6bc/07e8 */
|
||||
ULONG GdiClientPID; /* 6c0/07f0 */
|
||||
ULONG GdiClientTID; /* 6c4/07f4 */
|
||||
PVOID GdiThreadLocaleInfo; /* 6c8/07f8 */
|
||||
ULONG_PTR Win32ClientInfo[62]; /* 6cc/0800 */
|
||||
PVOID glDispatchTable[233]; /* 7c4/09f0 */
|
||||
PVOID glReserved1[29]; /* b68/1138 */
|
||||
PVOID glReserved2; /* bdc/1220 */
|
||||
PVOID glSectionInfo; /* be0/1228 */
|
||||
PVOID glSection; /* be4/1230 */
|
||||
PVOID glTable; /* be8/1238 */
|
||||
PVOID glCurrentRC; /* bec/1240 */
|
||||
PVOID glContext; /* bf0/1248 */
|
||||
ULONG LastStatusValue; /* bf4/1250 */
|
||||
UNICODE_STRING StaticUnicodeString; /* bf8/1258 */
|
||||
WCHAR StaticUnicodeBuffer[261]; /* c00/1268 */
|
||||
PVOID DeallocationStack; /* e0c/1478 */
|
||||
PVOID TlsSlots[64]; /* e10/1480 */
|
||||
LIST_ENTRY TlsLinks; /* f10/1680 */
|
||||
PVOID Vdm; /* f18/1690 */
|
||||
PVOID ReservedForNtRpc; /* f1c/1698 */
|
||||
PVOID DbgSsReserved[2]; /* f20/16a0 */
|
||||
ULONG HardErrorMode; /* f28/16b0 */
|
||||
#ifdef _WIN64
|
||||
PVOID Instrumentation[11]; /* /16b8 */
|
||||
#else
|
||||
PVOID Instrumentation[9]; /* f2c/ */
|
||||
#endif
|
||||
GUID ActivityId; /* f50/1710 */
|
||||
PVOID SubProcessTag; /* f60/1720 */
|
||||
PVOID PerflibData; /* f64/1728 */
|
||||
PVOID EtwTraceData; /* f68/1730 */
|
||||
PVOID WinSockData; /* f6c/1738 */
|
||||
ULONG GdiBatchCount; /* f70/1740 */
|
||||
ULONG IdealProcessorValue; /* f74/1744 */
|
||||
ULONG GuaranteedStackBytes; /* f78/1748 */
|
||||
PVOID ReservedForPerf; /* f7c/1750 */
|
||||
PVOID ReservedForOle; /* f80/1758 */
|
||||
ULONG WaitingOnLoaderLock; /* f84/1760 */
|
||||
PVOID SavedPriorityState; /* f88/1768 */
|
||||
ULONG_PTR ReservedForCodeCoverage; /* f8c/1770 */
|
||||
PVOID ThreadPoolData; /* f90/1778 */
|
||||
PVOID* TlsExpansionSlots; /* f94/1780 */
|
||||
#ifdef _WIN64
|
||||
union {
|
||||
PVOID DeallocationBStore; /* /1788 */
|
||||
PVOID* ChpeV2CpuAreaInfo; /* /1788 */
|
||||
} DUMMYUNIONNAME;
|
||||
PVOID BStoreLimit; /* /1790 */
|
||||
#endif
|
||||
ULONG MuiGeneration; /* f98/1798 */
|
||||
ULONG IsImpersonating; /* f9c/179c */
|
||||
PVOID NlsCache; /* fa0/17a0 */
|
||||
PVOID ShimData; /* fa4/17a8 */
|
||||
ULONG HeapVirtualAffinity; /* fa8/17b0 */
|
||||
PVOID CurrentTransactionHandle; /* fac/17b8 */
|
||||
TEB_ACTIVE_FRAME* ActiveFrame; /* fb0/17c0 */
|
||||
PVOID* FlsSlots; /* fb4/17c8 */
|
||||
PVOID PreferredLanguages; /* fb8/17d0 */
|
||||
PVOID UserPrefLanguages; /* fbc/17d8 */
|
||||
PVOID MergedPrefLanguages; /* fc0/17e0 */
|
||||
ULONG MuiImpersonation; /* fc4/17e8 */
|
||||
USHORT CrossTebFlags; /* fc8/17ec */
|
||||
USHORT SameTebFlags; /* fca/17ee */
|
||||
PVOID TxnScopeEnterCallback; /* fcc/17f0 */
|
||||
PVOID TxnScopeExitCallback; /* fd0/17f8 */
|
||||
PVOID TxnScopeContext; /* fd4/1800 */
|
||||
ULONG LockCount; /* fd8/1808 */
|
||||
LONG WowTebOffset; /* fdc/180c */
|
||||
PVOID ResourceRetValue; /* fe0/1810 */
|
||||
PVOID ReservedForWdf; /* fe4/1818 */
|
||||
ULONGLONG ReservedForCrt; /* fe8/1820 */
|
||||
GUID EffectiveContainerId; /* ff0/1828 */
|
||||
} TEB, *PTEB;
|
||||
static_assert(offsetof(TEB, DeallocationStack) ==
|
||||
0x1478); /* The only member we care about at the moment */
|
||||
|
||||
typedef enum _QUEUE_USER_APC_FLAGS {
|
||||
QueueUserApcFlagsNone,
|
||||
QueueUserApcFlagsSpecialUserApc,
|
||||
QueueUserApcFlagsMaxValue
|
||||
} QUEUE_USER_APC_FLAGS;
|
||||
|
||||
typedef union _USER_APC_OPTION {
|
||||
ULONG_PTR UserApcFlags;
|
||||
HANDLE MemoryReserveHandle;
|
||||
} USER_APC_OPTION, *PUSER_APC_OPTION;
|
||||
|
||||
using PPS_APC_ROUTINE = void (*)(PVOID ApcArgument1, PVOID ApcArgument2, PVOID ApcArgument3,
|
||||
PCONTEXT Context);
|
||||
|
||||
typedef u64(__stdcall* NtClose_t)(HANDLE Handle);
|
||||
|
||||
typedef u64(__stdcall* NtSetInformationFile_t)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock,
|
||||
PVOID FileInformation, ULONG Length,
|
||||
FILE_INFORMATION_CLASS FileInformationClass);
|
||||
|
||||
typedef u64(__stdcall* NtCreateThread_t)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess,
|
||||
PCOBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle,
|
||||
PCLIENT_ID ClientId, PCONTEXT ThreadContext,
|
||||
PINITIAL_TEB InitialTeb, BOOLEAN CreateSuspended);
|
||||
|
||||
typedef u64(__stdcall* NtTerminateThread_t)(HANDLE ThreadHandle, u64 ExitStatus);
|
||||
|
||||
typedef u64(__stdcall* NtQueueApcThreadEx_t)(HANDLE ThreadHandle,
|
||||
USER_APC_OPTION UserApcReserveHandle,
|
||||
PPS_APC_ROUTINE ApcRoutine, PVOID ApcArgument1,
|
||||
PVOID ApcArgument2, PVOID ApcArgument3);
|
||||
|
||||
extern NtClose_t NtClose;
|
||||
extern NtSetInformationFile_t NtSetInformationFile;
|
||||
extern NtCreateThread_t NtCreateThread;
|
||||
extern NtTerminateThread_t NtTerminateThread;
|
||||
extern NtQueueApcThreadEx_t NtQueueApcThreadEx;
|
||||
|
||||
namespace Common::NtApi {
|
||||
void Initialize();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -176,6 +176,34 @@ void SetUserPath(PathType shad_path, const fs::path& new_path) {
|
||||
UserPaths.insert_or_assign(shad_path, new_path);
|
||||
}
|
||||
|
||||
std::optional<fs::path> FindGameByID(const fs::path& dir, const std::string& game_id,
|
||||
int max_depth) {
|
||||
if (max_depth < 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Check if this is the game we're looking for
|
||||
if (dir.filename() == game_id && fs::exists(dir / "sce_sys" / "param.sfo")) {
|
||||
auto eboot_path = dir / "eboot.bin";
|
||||
if (fs::exists(eboot_path)) {
|
||||
return eboot_path;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively search subdirectories
|
||||
std::error_code ec;
|
||||
for (const auto& entry : fs::directory_iterator(dir, ec)) {
|
||||
if (!entry.is_directory()) {
|
||||
continue;
|
||||
}
|
||||
if (auto found = FindGameByID(entry.path(), game_id, max_depth - 1)) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
void PathToQString(QString& result, const std::filesystem::path& path) {
|
||||
#ifdef _WIN32
|
||||
|
@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
@ -115,4 +116,18 @@ void PathToQString(QString& result, const std::filesystem::path& path);
|
||||
[[nodiscard]] std::filesystem::path PathFromQString(const QString& path);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Recursively searches for a game directory by its ID.
|
||||
* Limits search depth to prevent excessive filesystem traversal.
|
||||
*
|
||||
* @param dir Base directory to start the search from
|
||||
* @param game_id The game ID to search for
|
||||
* @param max_depth Maximum directory depth to search
|
||||
*
|
||||
* @returns Path to eboot.bin if found, std::nullopt otherwise
|
||||
*/
|
||||
[[nodiscard]] std::optional<std::filesystem::path> FindGameByID(const std::filesystem::path& dir,
|
||||
const std::string& game_id,
|
||||
int max_depth);
|
||||
|
||||
} // namespace Common::FS
|
||||
|
@ -6,14 +6,18 @@
|
||||
#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 {
|
||||
|
||||
const char g_scm_rev[] = GIT_REV;
|
||||
const char g_scm_branch[] = GIT_BRANCH;
|
||||
const char g_scm_desc[] = GIT_DESC;
|
||||
const char g_scm_date[] = BUILD_DATE;
|
||||
const char g_scm_rev[] = GIT_REV;
|
||||
const char g_scm_branch[] = GIT_BRANCH;
|
||||
const char g_scm_desc[] = GIT_DESC;
|
||||
const char g_scm_remote_name[] = GIT_REMOTE_NAME;
|
||||
const char g_scm_remote_url[] = GIT_REMOTE_URL;
|
||||
const char g_scm_date[] = BUILD_DATE;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -8,6 +8,8 @@ namespace Common {
|
||||
extern const char g_scm_rev[];
|
||||
extern const char g_scm_branch[];
|
||||
extern const char g_scm_desc[];
|
||||
extern const char g_scm_remote_name[];
|
||||
extern const char g_scm_remote_url[];
|
||||
extern const char g_scm_date[];
|
||||
|
||||
} // namespace Common
|
||||
|
163
src/common/slab_heap.h
Normal file
163
src/common/slab_heap.h
Normal file
@ -0,0 +1,163 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include "common/assert.h"
|
||||
#include "common/spin_lock.h"
|
||||
|
||||
namespace Common {
|
||||
|
||||
class SlabHeapImpl {
|
||||
public:
|
||||
struct Node {
|
||||
Node* next{};
|
||||
};
|
||||
|
||||
public:
|
||||
constexpr SlabHeapImpl() = default;
|
||||
|
||||
void Initialize() {
|
||||
ASSERT(m_head == nullptr);
|
||||
}
|
||||
|
||||
Node* GetHead() const {
|
||||
return m_head;
|
||||
}
|
||||
|
||||
void* Allocate() {
|
||||
m_lock.lock();
|
||||
|
||||
Node* ret = m_head;
|
||||
if (ret != nullptr) {
|
||||
m_head = ret->next;
|
||||
}
|
||||
|
||||
m_lock.unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Free(void* obj) {
|
||||
m_lock.lock();
|
||||
|
||||
Node* node = static_cast<Node*>(obj);
|
||||
node->next = m_head;
|
||||
m_head = node;
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic<Node*> m_head{};
|
||||
Common::SpinLock m_lock;
|
||||
};
|
||||
|
||||
class SlabHeapBase : protected SlabHeapImpl {
|
||||
private:
|
||||
size_t m_obj_size{};
|
||||
uintptr_t m_peak{};
|
||||
uintptr_t m_start{};
|
||||
uintptr_t m_end{};
|
||||
|
||||
public:
|
||||
constexpr SlabHeapBase() = default;
|
||||
|
||||
bool Contains(uintptr_t address) const {
|
||||
return m_start <= address && address < m_end;
|
||||
}
|
||||
|
||||
void Initialize(size_t obj_size, void* memory, size_t memory_size) {
|
||||
// Ensure we don't initialize a slab using null memory.
|
||||
ASSERT(memory != nullptr);
|
||||
|
||||
// Set our object size.
|
||||
m_obj_size = obj_size;
|
||||
|
||||
// Initialize the base allocator.
|
||||
SlabHeapImpl::Initialize();
|
||||
|
||||
// Set our tracking variables.
|
||||
const size_t num_obj = (memory_size / obj_size);
|
||||
m_start = reinterpret_cast<uintptr_t>(memory);
|
||||
m_end = m_start + num_obj * obj_size;
|
||||
m_peak = m_start;
|
||||
|
||||
// Free the objects.
|
||||
u8* cur = reinterpret_cast<u8*>(m_end);
|
||||
|
||||
for (size_t i = 0; i < num_obj; i++) {
|
||||
cur -= obj_size;
|
||||
SlabHeapImpl::Free(cur);
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetSlabHeapSize() const {
|
||||
return (m_end - m_start) / this->GetObjectSize();
|
||||
}
|
||||
|
||||
size_t GetObjectSize() const {
|
||||
return m_obj_size;
|
||||
}
|
||||
|
||||
void* Allocate() {
|
||||
void* obj = SlabHeapImpl::Allocate();
|
||||
return obj;
|
||||
}
|
||||
|
||||
void Free(void* obj) {
|
||||
// Don't allow freeing an object that wasn't allocated from this heap.
|
||||
const bool contained = this->Contains(reinterpret_cast<uintptr_t>(obj));
|
||||
ASSERT(contained);
|
||||
SlabHeapImpl::Free(obj);
|
||||
}
|
||||
|
||||
size_t GetObjectIndex(const void* obj) const {
|
||||
return (reinterpret_cast<uintptr_t>(obj) - m_start) / this->GetObjectSize();
|
||||
}
|
||||
|
||||
size_t GetPeakIndex() const {
|
||||
return this->GetObjectIndex(reinterpret_cast<const void*>(m_peak));
|
||||
}
|
||||
|
||||
uintptr_t GetSlabHeapAddress() const {
|
||||
return m_start;
|
||||
}
|
||||
|
||||
size_t GetNumRemaining() const {
|
||||
// Only calculate the number of remaining objects under debug configuration.
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SlabHeap final : public SlabHeapBase {
|
||||
private:
|
||||
using BaseHeap = SlabHeapBase;
|
||||
|
||||
public:
|
||||
constexpr SlabHeap() = default;
|
||||
|
||||
void Initialize(void* memory, size_t memory_size) {
|
||||
BaseHeap::Initialize(sizeof(T), memory, memory_size);
|
||||
}
|
||||
|
||||
T* Allocate() {
|
||||
T* obj = static_cast<T*>(BaseHeap::Allocate());
|
||||
|
||||
if (obj != nullptr) [[likely]] {
|
||||
std::construct_at(obj);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
void Free(T* obj) {
|
||||
BaseHeap::Free(obj);
|
||||
}
|
||||
|
||||
size_t GetObjectIndex(const T* obj) const {
|
||||
return BaseHeap::GetObjectIndex(obj);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Common
|
@ -3,10 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bit>
|
||||
#include <compare>
|
||||
#include <numeric>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include "common/assert.h"
|
||||
|
53
src/common/spin_lock.cpp
Executable file
53
src/common/spin_lock.cpp
Executable file
@ -0,0 +1,53 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/spin_lock.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#include <intrin.h>
|
||||
#if _M_AMD64
|
||||
#define __x86_64__ 1
|
||||
#endif
|
||||
#if _M_ARM64
|
||||
#define __aarch64__ 1
|
||||
#endif
|
||||
#else
|
||||
#if __x86_64__
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
void ThreadPause() {
|
||||
#if __x86_64__
|
||||
_mm_pause();
|
||||
#elif __aarch64__ && _MSC_VER
|
||||
__yield();
|
||||
#elif __aarch64__
|
||||
asm("yield");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
namespace Common {
|
||||
|
||||
void SpinLock::lock() {
|
||||
while (lck.test_and_set(std::memory_order_acquire)) {
|
||||
ThreadPause();
|
||||
}
|
||||
}
|
||||
|
||||
void SpinLock::unlock() {
|
||||
lck.clear(std::memory_order_release);
|
||||
}
|
||||
|
||||
bool SpinLock::try_lock() {
|
||||
if (lck.test_and_set(std::memory_order_acquire)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Common
|
33
src/common/spin_lock.h
Executable file
33
src/common/spin_lock.h
Executable file
@ -0,0 +1,33 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/**
|
||||
* SpinLock class
|
||||
* a lock similar to mutex that forces a thread to spin wait instead calling the
|
||||
* supervisor. Should be used on short sequences of code.
|
||||
*/
|
||||
class SpinLock {
|
||||
public:
|
||||
SpinLock() = default;
|
||||
|
||||
SpinLock(const SpinLock&) = delete;
|
||||
SpinLock& operator=(const SpinLock&) = delete;
|
||||
|
||||
SpinLock(SpinLock&&) = delete;
|
||||
SpinLock& operator=(SpinLock&&) = delete;
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
[[nodiscard]] bool try_lock();
|
||||
|
||||
private:
|
||||
std::atomic_flag lck = ATOMIC_FLAG_INIT;
|
||||
};
|
||||
|
||||
} // namespace Common
|
7
src/common/stb.cpp
Normal file
7
src/common/stb.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#define STBI_ONLY_PNG
|
||||
#define STBI_NO_STDIO
|
||||
#include "common/stb.h"
|
6
src/common/stb.h
Normal file
6
src/common/stb.h
Normal file
@ -0,0 +1,6 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stb_image.h>
|
@ -37,6 +37,10 @@ std::vector<std::string> SplitString(const std::string& str, char delimiter) {
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string_view U8stringToString(std::u8string_view u8str) {
|
||||
return std::string_view{reinterpret_cast<const char*>(u8str.data()), u8str.size()};
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static std::wstring CPToUTF16(u32 code_page, std::string_view input) {
|
||||
const auto size =
|
||||
|
@ -16,6 +16,8 @@ void ToLowerInPlace(std::string& str);
|
||||
|
||||
std::vector<std::string> SplitString(const std::string& str, char delimiter);
|
||||
|
||||
std::string_view U8stringToString(std::u8string_view u8str);
|
||||
|
||||
#ifdef _WIN32
|
||||
[[nodiscard]] std::string UTF16ToUTF8(std::wstring_view input);
|
||||
[[nodiscard]] std::wstring UTF8ToUTF16W(std::string_view str);
|
||||
|
17
src/common/support/avdec.h
Normal file
17
src/common/support/avdec.h
Normal file
@ -0,0 +1,17 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
// support header file for libav
|
||||
|
||||
// The av_err2str macro in libavutil/error.h does not play nice with C++
|
||||
#ifdef av_err2str
|
||||
#undef av_err2str
|
||||
#include <string>
|
||||
av_always_inline std::string av_err2string(int errnum) {
|
||||
char errbuf[AV_ERROR_MAX_STRING_SIZE];
|
||||
return av_make_error_string(errbuf, AV_ERROR_MAX_STRING_SIZE, errnum);
|
||||
}
|
||||
#define av_err2str(err) av_err2string(err).c_str()
|
||||
#endif // av_err2str
|
@ -147,6 +147,10 @@ void SetCurrentThreadName(const char* name) {
|
||||
SetThreadDescription(GetCurrentThread(), UTF8ToUTF16W(name).data());
|
||||
}
|
||||
|
||||
void SetThreadName(void* thread, const char* name) {
|
||||
SetThreadDescription(thread, UTF8ToUTF16W(name).data());
|
||||
}
|
||||
|
||||
#else // !MSVC_VER, so must be POSIX threads
|
||||
|
||||
// MinGW with the POSIX threading model does not support pthread_setname_np
|
||||
@ -170,11 +174,19 @@ void SetCurrentThreadName(const char* name) {
|
||||
pthread_setname_np(pthread_self(), name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetThreadName(void* thread, const char* name) {
|
||||
// TODO
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
void SetCurrentThreadName(const char*) {
|
||||
// Do Nothing on MingW
|
||||
// Do Nothing on MinGW
|
||||
}
|
||||
|
||||
void SetThreadName(void* thread, const char* name) {
|
||||
// Do Nothing on MinGW
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -23,6 +23,8 @@ void SetCurrentThreadPriority(ThreadPriority new_priority);
|
||||
|
||||
void SetCurrentThreadName(const char* name);
|
||||
|
||||
void SetThreadName(void* thread, const char* name);
|
||||
|
||||
class AccurateTimer {
|
||||
std::chrono::nanoseconds target_interval{};
|
||||
std::chrono::nanoseconds total_wait{};
|
||||
@ -35,6 +37,10 @@ public:
|
||||
void Start();
|
||||
|
||||
void End();
|
||||
|
||||
std::chrono::nanoseconds GetTotalWait() const {
|
||||
return total_wait;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
@ -1,61 +1,61 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// General purpose function wrapper similar to std::function.
|
||||
/// Unlike std::function, the captured values don't have to be copyable.
|
||||
/// This class can be moved but not copied.
|
||||
template <typename ResultType, typename... Args>
|
||||
class UniqueFunction {
|
||||
class CallableBase {
|
||||
public:
|
||||
virtual ~CallableBase() = default;
|
||||
virtual ResultType operator()(Args&&...) = 0;
|
||||
};
|
||||
|
||||
template <typename Functor>
|
||||
class Callable final : public CallableBase {
|
||||
public:
|
||||
Callable(Functor&& functor_) : functor{std::move(functor_)} {}
|
||||
~Callable() override = default;
|
||||
|
||||
ResultType operator()(Args&&... args) override {
|
||||
return functor(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
Functor functor;
|
||||
};
|
||||
|
||||
public:
|
||||
UniqueFunction() = default;
|
||||
|
||||
template <typename Functor>
|
||||
UniqueFunction(Functor&& functor)
|
||||
: callable{std::make_unique<Callable<Functor>>(std::move(functor))} {}
|
||||
|
||||
UniqueFunction& operator=(UniqueFunction&& rhs) noexcept = default;
|
||||
UniqueFunction(UniqueFunction&& rhs) noexcept = default;
|
||||
|
||||
UniqueFunction& operator=(const UniqueFunction&) = delete;
|
||||
UniqueFunction(const UniqueFunction&) = delete;
|
||||
|
||||
ResultType operator()(Args&&... args) const {
|
||||
return (*callable)(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return static_cast<bool>(callable);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<CallableBase> callable;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace Common {
|
||||
|
||||
/// General purpose function wrapper similar to std::function.
|
||||
/// Unlike std::function, the captured values don't have to be copyable.
|
||||
/// This class can be moved but not copied.
|
||||
template <typename ResultType, typename... Args>
|
||||
class UniqueFunction {
|
||||
class CallableBase {
|
||||
public:
|
||||
virtual ~CallableBase() = default;
|
||||
virtual ResultType operator()(Args&&...) = 0;
|
||||
};
|
||||
|
||||
template <typename Functor>
|
||||
class Callable final : public CallableBase {
|
||||
public:
|
||||
Callable(Functor&& functor_) : functor{std::move(functor_)} {}
|
||||
~Callable() override = default;
|
||||
|
||||
ResultType operator()(Args&&... args) override {
|
||||
return functor(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
private:
|
||||
Functor functor;
|
||||
};
|
||||
|
||||
public:
|
||||
UniqueFunction() = default;
|
||||
|
||||
template <typename Functor>
|
||||
UniqueFunction(Functor&& functor)
|
||||
: callable{std::make_unique<Callable<Functor>>(std::move(functor))} {}
|
||||
|
||||
UniqueFunction& operator=(UniqueFunction&& rhs) noexcept = default;
|
||||
UniqueFunction(UniqueFunction&& rhs) noexcept = default;
|
||||
|
||||
UniqueFunction& operator=(const UniqueFunction&) = delete;
|
||||
UniqueFunction(const UniqueFunction&) = delete;
|
||||
|
||||
ResultType operator()(Args&&... args) const {
|
||||
return (*callable)(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return static_cast<bool>(callable);
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<CallableBase> callable;
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
|
111
src/common/va_ctx.h
Normal file
111
src/common/va_ctx.h
Normal file
@ -0,0 +1,111 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
#include <xmmintrin.h>
|
||||
#include "common/types.h"
|
||||
|
||||
#define VA_ARGS \
|
||||
uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, \
|
||||
uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, __m128 xmm2, __m128 xmm3, \
|
||||
__m128 xmm4, __m128 xmm5, __m128 xmm6, __m128 xmm7, ...
|
||||
|
||||
#define VA_CTX(ctx) \
|
||||
alignas(16)::Common::VaCtx ctx{}; \
|
||||
(ctx).reg_save_area.gp[0] = rdi; \
|
||||
(ctx).reg_save_area.gp[1] = rsi; \
|
||||
(ctx).reg_save_area.gp[2] = rdx; \
|
||||
(ctx).reg_save_area.gp[3] = rcx; \
|
||||
(ctx).reg_save_area.gp[4] = r8; \
|
||||
(ctx).reg_save_area.gp[5] = r9; \
|
||||
(ctx).reg_save_area.fp[0] = xmm0; \
|
||||
(ctx).reg_save_area.fp[1] = xmm1; \
|
||||
(ctx).reg_save_area.fp[2] = xmm2; \
|
||||
(ctx).reg_save_area.fp[3] = xmm3; \
|
||||
(ctx).reg_save_area.fp[4] = xmm4; \
|
||||
(ctx).reg_save_area.fp[5] = xmm5; \
|
||||
(ctx).reg_save_area.fp[6] = xmm6; \
|
||||
(ctx).reg_save_area.fp[7] = xmm7; \
|
||||
(ctx).va_list.reg_save_area = &(ctx).reg_save_area; \
|
||||
(ctx).va_list.gp_offset = offsetof(::Common::VaRegSave, gp); \
|
||||
(ctx).va_list.fp_offset = offsetof(::Common::VaRegSave, fp); \
|
||||
(ctx).va_list.overflow_arg_area = &overflow_arg_area;
|
||||
|
||||
namespace Common {
|
||||
|
||||
// https://stackoverflow.com/questions/4958384/what-is-the-format-of-the-x86-64-va-list-structure
|
||||
|
||||
struct VaList {
|
||||
u32 gp_offset;
|
||||
u32 fp_offset;
|
||||
void* overflow_arg_area;
|
||||
void* reg_save_area;
|
||||
};
|
||||
|
||||
struct VaRegSave {
|
||||
u64 gp[6];
|
||||
__m128 fp[8];
|
||||
};
|
||||
|
||||
struct VaCtx {
|
||||
VaRegSave reg_save_area;
|
||||
VaList va_list;
|
||||
};
|
||||
|
||||
template <class T, uint32_t Size>
|
||||
T vaArgRegSaveAreaGp(VaList* l) {
|
||||
auto* addr = reinterpret_cast<T*>(static_cast<u8*>(l->reg_save_area) + l->gp_offset);
|
||||
l->gp_offset += Size;
|
||||
return *addr;
|
||||
}
|
||||
template <class T, u64 Align, u64 Size>
|
||||
T vaArgOverflowArgArea(VaList* l) {
|
||||
auto ptr = ((reinterpret_cast<u64>(l->overflow_arg_area) + (Align - 1)) & ~(Align - 1));
|
||||
auto* addr = reinterpret_cast<T*>(ptr);
|
||||
l->overflow_arg_area = reinterpret_cast<void*>(ptr + Size);
|
||||
return *addr;
|
||||
}
|
||||
|
||||
template <class T, uint32_t Size>
|
||||
T vaArgRegSaveAreaFp(VaList* l) {
|
||||
auto* addr = reinterpret_cast<T*>(static_cast<u8*>(l->reg_save_area) + l->fp_offset);
|
||||
l->fp_offset += Size;
|
||||
return *addr;
|
||||
}
|
||||
|
||||
inline int vaArgInteger(VaList* l) {
|
||||
if (l->gp_offset <= 40) {
|
||||
return vaArgRegSaveAreaGp<int, 8>(l);
|
||||
}
|
||||
return vaArgOverflowArgArea<int, 1, 8>(l);
|
||||
}
|
||||
|
||||
inline long long vaArgLongLong(VaList* l) {
|
||||
if (l->gp_offset <= 40) {
|
||||
return vaArgRegSaveAreaGp<long long, 8>(l);
|
||||
}
|
||||
return vaArgOverflowArgArea<long long, 1, 8>(l);
|
||||
}
|
||||
inline long vaArgLong(VaList* l) {
|
||||
if (l->gp_offset <= 40) {
|
||||
return vaArgRegSaveAreaGp<long, 8>(l);
|
||||
}
|
||||
return vaArgOverflowArgArea<long, 1, 8>(l);
|
||||
}
|
||||
|
||||
inline double vaArgDouble(VaList* l) {
|
||||
if (l->fp_offset <= 160) {
|
||||
return vaArgRegSaveAreaFp<double, 16>(l);
|
||||
}
|
||||
return vaArgOverflowArgArea<double, 1, 8>(l);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* vaArgPtr(VaList* l) {
|
||||
if (l->gp_offset <= 40) {
|
||||
return vaArgRegSaveAreaGp<T*, 8>(l);
|
||||
}
|
||||
return vaArgOverflowArgArea<T*, 1, 8>(l);
|
||||
}
|
||||
|
||||
} // namespace Common
|
@ -8,7 +8,7 @@
|
||||
|
||||
namespace Common {
|
||||
|
||||
constexpr char VERSION[] = "0.4.1 WIP";
|
||||
constexpr char VERSION[] = "0.6.1 WIP";
|
||||
constexpr bool isRelease = false;
|
||||
|
||||
} // namespace Common
|
||||
|
@ -1,13 +1,14 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <map>
|
||||
#include <boost/icl/separate_interval_set.hpp>
|
||||
#include "common/alignment.h"
|
||||
#include "common/arch.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/error.h"
|
||||
#include "core/address_space.h"
|
||||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "core/libraries/kernel/memory.h"
|
||||
#include "core/memory.h"
|
||||
#include "libraries/error_codes.h"
|
||||
|
||||
@ -25,7 +26,7 @@ asm(".zerofill GUEST_SYSTEM,GUEST_SYSTEM,__guest_system,0xFBFC00000");
|
||||
|
||||
namespace Core {
|
||||
|
||||
static constexpr size_t BackingSize = SCE_KERNEL_MAIN_DMEM_SIZE_PRO;
|
||||
static constexpr size_t BackingSize = SCE_KERNEL_TOTAL_MEM_PRO;
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
@ -40,6 +41,12 @@ static constexpr size_t BackingSize = SCE_KERNEL_MAIN_DMEM_SIZE_PRO;
|
||||
}
|
||||
}
|
||||
|
||||
struct MemoryRegion {
|
||||
VAddr base;
|
||||
size_t size;
|
||||
bool is_mapped;
|
||||
};
|
||||
|
||||
struct AddressSpace::Impl {
|
||||
Impl() : process{GetCurrentProcess()} {
|
||||
// Allocate virtual address placeholder for our address space.
|
||||
@ -60,27 +67,25 @@ struct AddressSpace::Impl {
|
||||
static constexpr size_t ReductionOnFail = 1_GB;
|
||||
static constexpr size_t MaxReductions = 10;
|
||||
|
||||
size_t reduction = 0;
|
||||
size_t virtual_size = SystemManagedSize + SystemReservedSize + UserSize;
|
||||
for (u32 i = 0; i < MaxReductions; i++) {
|
||||
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size - reduction,
|
||||
virtual_base = static_cast<u8*>(VirtualAlloc2(process, NULL, virtual_size,
|
||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER,
|
||||
PAGE_NOACCESS, ¶m, 1));
|
||||
if (virtual_base) {
|
||||
break;
|
||||
}
|
||||
reduction += ReductionOnFail;
|
||||
virtual_size -= ReductionOnFail;
|
||||
}
|
||||
ASSERT_MSG(virtual_base, "Unable to reserve virtual address space: {}",
|
||||
Common::GetLastErrorMsg());
|
||||
|
||||
// Take the reduction off of the system managed area, and leave the others unchanged.
|
||||
system_managed_base = virtual_base;
|
||||
system_managed_size = SystemManagedSize - reduction;
|
||||
system_reserved_base = reinterpret_cast<u8*>(SYSTEM_RESERVED_MIN);
|
||||
system_reserved_size = SystemReservedSize;
|
||||
system_managed_base = virtual_base;
|
||||
system_managed_size = system_reserved_base - virtual_base;
|
||||
user_base = reinterpret_cast<u8*>(USER_MIN);
|
||||
user_size = UserSize;
|
||||
user_size = virtual_base + virtual_size - user_base;
|
||||
|
||||
LOG_INFO(Kernel_Vmm, "System managed virtual memory region: {} - {}",
|
||||
fmt::ptr(system_managed_base),
|
||||
@ -93,9 +98,8 @@ struct AddressSpace::Impl {
|
||||
|
||||
// Initializer placeholder tracker
|
||||
const uintptr_t system_managed_addr = reinterpret_cast<uintptr_t>(system_managed_base);
|
||||
const uintptr_t system_reserved_addr = reinterpret_cast<uintptr_t>(system_reserved_base);
|
||||
const uintptr_t user_addr = reinterpret_cast<uintptr_t>(user_base);
|
||||
placeholders.insert({system_managed_addr, virtual_size - reduction});
|
||||
regions.emplace(system_managed_addr,
|
||||
MemoryRegion{system_managed_addr, virtual_size, false});
|
||||
|
||||
// Allocate backing file that represents the total physical memory.
|
||||
backing_handle =
|
||||
@ -132,42 +136,15 @@ struct AddressSpace::Impl {
|
||||
}
|
||||
|
||||
void* Map(VAddr virtual_addr, PAddr phys_addr, size_t size, ULONG prot, uintptr_t fd = 0) {
|
||||
const size_t aligned_size = Common::AlignUp(size, 16_KB);
|
||||
const auto it = placeholders.find(virtual_addr);
|
||||
ASSERT_MSG(it != placeholders.end(), "Cannot map already mapped region");
|
||||
ASSERT_MSG(virtual_addr >= it->lower() && virtual_addr + aligned_size <= it->upper(),
|
||||
"Map range must be fully contained in a placeholder");
|
||||
|
||||
// Windows only allows splitting a placeholder into two.
|
||||
// This means that if the map range is fully
|
||||
// contained the the placeholder we need to perform two split operations,
|
||||
// one at the start and at the end.
|
||||
const VAddr placeholder_start = it->lower();
|
||||
const VAddr placeholder_end = it->upper();
|
||||
const VAddr virtual_end = virtual_addr + aligned_size;
|
||||
|
||||
// If the placeholder doesn't exactly start at virtual_addr, split it at the start.
|
||||
if (placeholder_start != virtual_addr) {
|
||||
VirtualFreeEx(process, reinterpret_cast<LPVOID>(placeholder_start),
|
||||
virtual_addr - placeholder_start, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
|
||||
}
|
||||
|
||||
// If the placeholder doesn't exactly end at virtual_end, split it at the end.
|
||||
if (placeholder_end != virtual_end) {
|
||||
VirtualFreeEx(process, reinterpret_cast<LPVOID>(virtual_end),
|
||||
placeholder_end - virtual_end, MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER);
|
||||
}
|
||||
|
||||
// Remove the placeholder.
|
||||
placeholders.erase({virtual_addr, virtual_end});
|
||||
|
||||
// Perform the map.
|
||||
// Before mapping we must carve a placeholder with the exact properties of our mapping.
|
||||
auto* region = EnsureSplitRegionForMapping(virtual_addr, size);
|
||||
region->is_mapped = true;
|
||||
void* ptr = nullptr;
|
||||
if (phys_addr != -1) {
|
||||
HANDLE backing = fd ? reinterpret_cast<HANDLE>(fd) : backing_handle;
|
||||
if (fd && prot == PAGE_READONLY) {
|
||||
DWORD resultvar;
|
||||
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), aligned_size,
|
||||
ptr = VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
||||
MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER,
|
||||
PAGE_READWRITE, nullptr, 0);
|
||||
bool ret = ReadFile(backing, ptr, size, &resultvar, NULL);
|
||||
@ -176,12 +153,11 @@ struct AddressSpace::Impl {
|
||||
ASSERT_MSG(ret, "VirtualProtect failed. {}", Common::GetLastErrorMsg());
|
||||
} else {
|
||||
ptr = MapViewOfFile3(backing, process, reinterpret_cast<PVOID>(virtual_addr),
|
||||
phys_addr, aligned_size, MEM_REPLACE_PLACEHOLDER, prot,
|
||||
nullptr, 0);
|
||||
phys_addr, size, MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||
}
|
||||
} else {
|
||||
ptr =
|
||||
VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), aligned_size,
|
||||
VirtualAlloc2(process, reinterpret_cast<PVOID>(virtual_addr), size,
|
||||
MEM_RESERVE | MEM_COMMIT | MEM_REPLACE_PLACEHOLDER, prot, nullptr, 0);
|
||||
}
|
||||
ASSERT_MSG(ptr, "{}", Common::GetLastErrorMsg());
|
||||
@ -202,33 +178,118 @@ struct AddressSpace::Impl {
|
||||
|
||||
// The unmap call will create a new placeholder region. We need to see if we can coalesce it
|
||||
// with neighbors.
|
||||
VAddr placeholder_start = virtual_addr;
|
||||
VAddr placeholder_end = virtual_addr + size;
|
||||
JoinRegionsAfterUnmap(virtual_addr, size);
|
||||
}
|
||||
|
||||
// The following code is inspired from Dolphin's MemArena
|
||||
// https://github.com/dolphin-emu/dolphin/blob/deee3ee4/Source/Core/Common/MemArenaWin.cpp#L212
|
||||
MemoryRegion* EnsureSplitRegionForMapping(VAddr address, size_t size) {
|
||||
// Find closest region that is <= the given address by using upper bound and decrementing
|
||||
auto it = regions.upper_bound(address);
|
||||
ASSERT_MSG(it != regions.begin(), "Invalid address {:#x}", address);
|
||||
--it;
|
||||
ASSERT_MSG(!it->second.is_mapped,
|
||||
"Attempt to map {:#x} with size {:#x} which overlaps with {:#x} mapping",
|
||||
address, size, it->second.base);
|
||||
auto& [base, region] = *it;
|
||||
|
||||
const VAddr mapping_address = region.base;
|
||||
const size_t region_size = region.size;
|
||||
if (mapping_address == address) {
|
||||
// If this region is already split up correctly we don't have to do anything
|
||||
if (region_size == size) {
|
||||
return ®ion;
|
||||
}
|
||||
|
||||
ASSERT_MSG(region_size >= size,
|
||||
"Region with address {:#x} and size {:#x} can't fit {:#x}", mapping_address,
|
||||
region_size, size);
|
||||
|
||||
// Split the placeholder.
|
||||
if (!VirtualFreeEx(process, LPVOID(address), size,
|
||||
MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER)) {
|
||||
UNREACHABLE_MSG("Region splitting failed: {}", Common::GetLastErrorMsg());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Update tracked mappings and return the first of the two
|
||||
region.size = size;
|
||||
const VAddr new_mapping_start = address + size;
|
||||
regions.emplace_hint(std::next(it), new_mapping_start,
|
||||
MemoryRegion(new_mapping_start, region_size - size, false));
|
||||
return ®ion;
|
||||
}
|
||||
|
||||
ASSERT(mapping_address < address);
|
||||
|
||||
// Is there enough space to map this?
|
||||
const size_t offset_in_region = address - mapping_address;
|
||||
const size_t minimum_size = size + offset_in_region;
|
||||
ASSERT(region_size >= minimum_size);
|
||||
|
||||
// Split the placeholder.
|
||||
if (!VirtualFreeEx(process, LPVOID(address), size,
|
||||
MEM_RELEASE | MEM_PRESERVE_PLACEHOLDER)) {
|
||||
UNREACHABLE_MSG("Region splitting failed: {}", Common::GetLastErrorMsg());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do we now have two regions or three regions?
|
||||
if (region_size == minimum_size) {
|
||||
// Split into two; update tracked mappings and return the second one
|
||||
region.size = offset_in_region;
|
||||
it = regions.emplace_hint(std::next(it), address, MemoryRegion(address, size, false));
|
||||
return &it->second;
|
||||
} else {
|
||||
// Split into three; update tracked mappings and return the middle one
|
||||
region.size = offset_in_region;
|
||||
const VAddr middle_mapping_start = address;
|
||||
const size_t middle_mapping_size = size;
|
||||
const VAddr after_mapping_start = address + size;
|
||||
const size_t after_mapping_size = region_size - minimum_size;
|
||||
it = regions.emplace_hint(std::next(it), after_mapping_start,
|
||||
MemoryRegion(after_mapping_start, after_mapping_size, false));
|
||||
it = regions.emplace_hint(
|
||||
it, middle_mapping_start,
|
||||
MemoryRegion(middle_mapping_start, middle_mapping_size, false));
|
||||
return &it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void JoinRegionsAfterUnmap(VAddr address, size_t size) {
|
||||
// There should be a mapping that matches the request exactly, find it
|
||||
auto it = regions.find(address);
|
||||
ASSERT_MSG(it != regions.end() && it->second.size == size,
|
||||
"Invalid address/size given to unmap.");
|
||||
auto& [base, region] = *it;
|
||||
region.is_mapped = false;
|
||||
|
||||
// Check if a placeholder exists right before us.
|
||||
const auto left_it = placeholders.find(virtual_addr - 1);
|
||||
if (left_it != placeholders.end()) {
|
||||
ASSERT_MSG(left_it->upper() == virtual_addr,
|
||||
"Left placeholder does not end at virtual_addr!");
|
||||
placeholder_start = left_it->lower();
|
||||
VirtualFreeEx(process, reinterpret_cast<LPVOID>(placeholder_start),
|
||||
placeholder_end - placeholder_start,
|
||||
MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
|
||||
auto it_prev = it != regions.begin() ? std::prev(it) : regions.end();
|
||||
if (it_prev != regions.end() && !it_prev->second.is_mapped) {
|
||||
const size_t total_size = it_prev->second.size + size;
|
||||
if (!VirtualFreeEx(process, LPVOID(it_prev->first), total_size,
|
||||
MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS)) {
|
||||
UNREACHABLE_MSG("Region coalescing failed: {}", Common::GetLastErrorMsg());
|
||||
}
|
||||
|
||||
it_prev->second.size = total_size;
|
||||
regions.erase(it);
|
||||
it = it_prev;
|
||||
}
|
||||
|
||||
// Check if a placeholder exists right after us.
|
||||
const auto right_it = placeholders.find(placeholder_end + 1);
|
||||
if (right_it != placeholders.end()) {
|
||||
ASSERT_MSG(right_it->lower() == placeholder_end,
|
||||
"Right placeholder does not start at virtual_end!");
|
||||
placeholder_end = right_it->upper();
|
||||
VirtualFreeEx(process, reinterpret_cast<LPVOID>(placeholder_start),
|
||||
placeholder_end - placeholder_start,
|
||||
MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS);
|
||||
}
|
||||
auto it_next = std::next(it);
|
||||
if (it_next != regions.end() && !it_next->second.is_mapped) {
|
||||
const size_t total_size = it->second.size + it_next->second.size;
|
||||
if (!VirtualFreeEx(process, LPVOID(it->first), total_size,
|
||||
MEM_RELEASE | MEM_COALESCE_PLACEHOLDERS)) {
|
||||
UNREACHABLE_MSG("Region coalescing failed: {}", Common::GetLastErrorMsg());
|
||||
}
|
||||
|
||||
// Insert the new placeholder.
|
||||
placeholders.insert({placeholder_start, placeholder_end});
|
||||
it->second.size = total_size;
|
||||
regions.erase(it_next);
|
||||
}
|
||||
}
|
||||
|
||||
void Protect(VAddr virtual_addr, size_t size, bool read, bool write, bool execute) {
|
||||
@ -251,18 +312,22 @@ struct AddressSpace::Impl {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD old_flags{};
|
||||
bool success =
|
||||
VirtualProtect(reinterpret_cast<void*>(virtual_addr), size, new_flags, &old_flags);
|
||||
|
||||
if (!success) {
|
||||
LOG_ERROR(Common_Memory,
|
||||
"Failed to change virtual memory protection for address {:#x}, size {}",
|
||||
virtual_addr, size);
|
||||
const VAddr virtual_end = virtual_addr + size;
|
||||
auto it = --regions.upper_bound(virtual_addr);
|
||||
for (; it->first < virtual_end; it++) {
|
||||
if (!it->second.is_mapped) {
|
||||
continue;
|
||||
}
|
||||
const auto& region = it->second;
|
||||
const size_t range_addr = std::max(region.base, virtual_addr);
|
||||
const size_t range_size = std::min(region.base + region.size, virtual_end) - range_addr;
|
||||
DWORD old_flags{};
|
||||
if (!VirtualProtectEx(process, LPVOID(range_addr), range_size, new_flags, &old_flags)) {
|
||||
UNREACHABLE_MSG(
|
||||
"Failed to change virtual memory protection for address {:#x}, size {}",
|
||||
range_addr, range_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Use assert to ensure success in debug builds
|
||||
DEBUG_ASSERT(success && "Failed to change virtual memory protection");
|
||||
}
|
||||
|
||||
HANDLE process{};
|
||||
@ -275,7 +340,7 @@ struct AddressSpace::Impl {
|
||||
size_t system_reserved_size{};
|
||||
u8* user_base{};
|
||||
size_t user_size{};
|
||||
boost::icl::separate_interval_set<uintptr_t> placeholders;
|
||||
std::map<VAddr, MemoryRegion> regions;
|
||||
};
|
||||
#else
|
||||
|
||||
|
@ -30,16 +30,6 @@
|
||||
|
||||
using namespace Xbyak::util;
|
||||
|
||||
#define MAYBE_AVX(OPCODE, ...) \
|
||||
[&] { \
|
||||
Cpu cpu; \
|
||||
if (cpu.has(Cpu::tAVX)) { \
|
||||
c.v##OPCODE(__VA_ARGS__); \
|
||||
} else { \
|
||||
c.OPCODE(__VA_ARGS__); \
|
||||
} \
|
||||
}()
|
||||
|
||||
namespace Core {
|
||||
|
||||
static Xbyak::Reg ZydisToXbyakRegister(const ZydisRegister reg) {
|
||||
@ -643,7 +633,7 @@ static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
||||
ASSERT_MSG(length + index <= 64, "length + index must be less than or equal to 64.");
|
||||
|
||||
// Get lower qword from xmm register
|
||||
MAYBE_AVX(movq, scratch1, xmm_dst);
|
||||
c.vmovq(scratch1, xmm_dst);
|
||||
|
||||
if (index != 0) {
|
||||
c.shr(scratch1, index);
|
||||
@ -656,7 +646,7 @@ static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
||||
|
||||
// Writeback to xmm register, extrq instruction says top 64-bits are undefined so we don't
|
||||
// care to preserve them
|
||||
MAYBE_AVX(movq, xmm_dst, scratch1);
|
||||
c.vmovq(xmm_dst, scratch1);
|
||||
|
||||
c.pop(scratch2);
|
||||
c.pop(scratch1);
|
||||
@ -690,7 +680,7 @@ static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
||||
c.push(mask);
|
||||
|
||||
// Construct the mask out of the length that resides in bottom 6 bits of source xmm
|
||||
MAYBE_AVX(movq, scratch1, xmm_src);
|
||||
c.vmovq(scratch1, xmm_src);
|
||||
c.mov(scratch2, scratch1);
|
||||
c.and_(scratch2, 0x3F);
|
||||
c.jz(length_zero);
|
||||
@ -711,10 +701,10 @@ static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenera
|
||||
c.and_(scratch1, 0x3F);
|
||||
c.mov(scratch2, scratch1); // cl now contains the shift amount
|
||||
|
||||
MAYBE_AVX(movq, scratch1, xmm_dst);
|
||||
c.vmovq(scratch1, xmm_dst);
|
||||
c.shr(scratch1, cl);
|
||||
c.and_(scratch1, mask);
|
||||
MAYBE_AVX(movq, xmm_dst, scratch1);
|
||||
c.vmovq(xmm_dst, scratch1);
|
||||
|
||||
c.pop(mask);
|
||||
c.pop(scratch2);
|
||||
@ -765,8 +755,8 @@ static void GenerateINSERTQ(const ZydisDecodedOperand* operands, Xbyak::CodeGene
|
||||
|
||||
ASSERT_MSG(length + index <= 64, "length + index must be less than or equal to 64.");
|
||||
|
||||
MAYBE_AVX(movq, scratch1, xmm_src);
|
||||
MAYBE_AVX(movq, scratch2, xmm_dst);
|
||||
c.vmovq(scratch1, xmm_src);
|
||||
c.vmovq(scratch2, xmm_dst);
|
||||
c.mov(mask, mask_value);
|
||||
|
||||
// src &= mask
|
||||
@ -784,12 +774,7 @@ static void GenerateINSERTQ(const ZydisDecodedOperand* operands, Xbyak::CodeGene
|
||||
c.or_(scratch2, scratch1);
|
||||
|
||||
// Insert scratch2 into low 64 bits of dst, upper 64 bits are unaffected
|
||||
Cpu cpu;
|
||||
if (cpu.has(Cpu::tAVX)) {
|
||||
c.vpinsrq(xmm_dst, xmm_dst, scratch2, 0);
|
||||
} else {
|
||||
c.pinsrq(xmm_dst, scratch2, 0);
|
||||
}
|
||||
c.vpinsrq(xmm_dst, xmm_dst, scratch2, 0);
|
||||
|
||||
c.pop(mask);
|
||||
c.pop(scratch2);
|
||||
@ -816,7 +801,7 @@ static void GenerateINSERTQ(const ZydisDecodedOperand* operands, Xbyak::CodeGene
|
||||
c.push(mask);
|
||||
|
||||
// Get upper 64 bits of src and copy it to mask and index
|
||||
MAYBE_AVX(pextrq, index, xmm_src, 1);
|
||||
c.vpextrq(index, xmm_src, 1);
|
||||
c.mov(mask, index);
|
||||
|
||||
// When length is 0, set it to 64
|
||||
@ -839,7 +824,7 @@ static void GenerateINSERTQ(const ZydisDecodedOperand* operands, Xbyak::CodeGene
|
||||
c.and_(index, 0x3F);
|
||||
|
||||
// src &= mask
|
||||
MAYBE_AVX(movq, scratch1, xmm_src);
|
||||
c.vmovq(scratch1, xmm_src);
|
||||
c.and_(scratch1, mask);
|
||||
|
||||
// mask = ~(mask << index)
|
||||
@ -851,12 +836,12 @@ static void GenerateINSERTQ(const ZydisDecodedOperand* operands, Xbyak::CodeGene
|
||||
c.shl(scratch1, cl);
|
||||
|
||||
// dst = (dst & mask) | src
|
||||
MAYBE_AVX(movq, scratch2, xmm_dst);
|
||||
c.vmovq(scratch2, xmm_dst);
|
||||
c.and_(scratch2, mask);
|
||||
c.or_(scratch2, scratch1);
|
||||
|
||||
// Upper 64 bits are undefined in insertq
|
||||
MAYBE_AVX(movq, xmm_dst, scratch2);
|
||||
c.vmovq(xmm_dst, scratch2);
|
||||
|
||||
c.pop(mask);
|
||||
c.pop(index);
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
/// Initializes a stack for the current thread for use by patch implementations.
|
||||
|
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
|
||||
@ -137,20 +138,20 @@ void Crypto::aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
|
||||
}
|
||||
}
|
||||
|
||||
void Crypto::decryptEFSM(std::span<CryptoPP::byte, 16> NPcommID,
|
||||
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) {
|
||||
|
||||
std::vector<CryptoPP::byte> TrophyKey = {0x21, 0xF4, 0x1A, 0x6B, 0xAD, 0x8A, 0x1D, 0x3E,
|
||||
0xCA, 0x7A, 0xD5, 0x86, 0xC1, 0x01, 0xB7, 0xA9};
|
||||
std::vector<CryptoPP::byte> TrophyIV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
// step 1: Encrypt NPcommID
|
||||
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt;
|
||||
encrypt.SetKeyWithIV(TrophyKey.data(), TrophyKey.size(), TrophyIV.data());
|
||||
|
||||
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());
|
||||
|
@ -32,7 +32,8 @@ public:
|
||||
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>, std::span<CryptoPP::byte, 16> efsmIv,
|
||||
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,
|
||||
|
@ -8,14 +8,17 @@
|
||||
#include "common/singleton.h"
|
||||
#include "debug_state.h"
|
||||
#include "devtools/widget/common.h"
|
||||
#include "libraries/kernel/time_management.h"
|
||||
#include "libraries/kernel/time.h"
|
||||
#include "libraries/system/msgdialog.h"
|
||||
#include "video_core/amdgpu/pm4_cmds.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
|
||||
using namespace DebugStateType;
|
||||
|
||||
DebugStateImpl& DebugState = *Common::Singleton<DebugStateImpl>::Instance();
|
||||
|
||||
bool DebugStateType::showing_debug_menu_bar = false;
|
||||
|
||||
static ThreadID ThisThreadID() {
|
||||
#ifdef _WIN32
|
||||
return GetCurrentThreadId();
|
||||
@ -142,37 +145,73 @@ void DebugStateImpl::PushQueueDump(QueueDump dump) {
|
||||
frame.queues.push_back(std::move(dump));
|
||||
}
|
||||
|
||||
void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const AmdGpu::Liverpool::Regs& regs, bool is_compute) {
|
||||
std::scoped_lock lock{frame_dump_list_mutex};
|
||||
std::optional<RegDump*> DebugStateImpl::GetRegDump(uintptr_t base_addr, uintptr_t header_addr) {
|
||||
const auto it = waiting_reg_dumps.find(header_addr);
|
||||
if (it == waiting_reg_dumps.end()) {
|
||||
return;
|
||||
return std::nullopt;
|
||||
}
|
||||
auto& frame = *it->second;
|
||||
waiting_reg_dumps.erase(it);
|
||||
waiting_reg_dumps_dbg.erase(waiting_reg_dumps_dbg.find(header_addr));
|
||||
auto& dump = frame.regs[header_addr - base_addr];
|
||||
dump.regs = regs;
|
||||
if (is_compute) {
|
||||
dump.is_compute = true;
|
||||
const auto& cs = dump.regs.cs_program;
|
||||
dump.cs_data = ComputerShaderDump{
|
||||
.cs_program = cs,
|
||||
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
||||
};
|
||||
} else {
|
||||
for (int i = 0; i < RegDump::MaxShaderStages; i++) {
|
||||
if (regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
auto code = stage->Code();
|
||||
dump.stages[i] = ShaderDump{
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
}
|
||||
return &frame.regs[header_addr - base_addr];
|
||||
}
|
||||
|
||||
void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const AmdGpu::Liverpool::Regs& regs) {
|
||||
std::scoped_lock lock{frame_dump_list_mutex};
|
||||
|
||||
auto dump = GetRegDump(base_addr, header_addr);
|
||||
if (!dump) {
|
||||
return;
|
||||
}
|
||||
|
||||
(*dump)->regs = regs;
|
||||
|
||||
for (int i = 0; i < RegDump::MaxShaderStages; i++) {
|
||||
if ((*dump)->regs.stage_enable.IsStageEnabled(i)) {
|
||||
auto stage = (*dump)->regs.ProgramForStage(i);
|
||||
if (stage->address_lo != 0) {
|
||||
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(stage->Address<u32*>());
|
||||
auto code = stage->Code();
|
||||
(*dump)->stages[i] = PipelineShaderProgramDump{
|
||||
.name = Vulkan::PipelineCache::GetShaderName(Shader::StageFromIndex(i),
|
||||
info.shader_hash),
|
||||
.hash = info.shader_hash,
|
||||
.user_data = *stage,
|
||||
.code = std::vector<u32>{code.begin(), code.end()},
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DebugStateImpl::PushRegsDumpCompute(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const CsState& cs_state) {
|
||||
std::scoped_lock lock{frame_dump_list_mutex};
|
||||
|
||||
auto dump = GetRegDump(base_addr, header_addr);
|
||||
if (!dump) {
|
||||
return;
|
||||
}
|
||||
|
||||
(*dump)->is_compute = true;
|
||||
auto& cs = (*dump)->regs.cs_program;
|
||||
cs = cs_state;
|
||||
|
||||
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(cs.Address<u32*>());
|
||||
(*dump)->cs_data = PipelineComputerProgramDump{
|
||||
.name = Vulkan::PipelineCache::GetShaderName(Shader::Stage::Compute, info.shader_hash),
|
||||
.hash = info.shader_hash,
|
||||
.cs_program = cs,
|
||||
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
||||
};
|
||||
}
|
||||
|
||||
void DebugStateImpl::CollectShader(const std::string& name, Shader::LogicalStage l_stage,
|
||||
vk::ShaderModule module, std::span<const u32> spv,
|
||||
std::span<const u32> raw_code, std::span<const u32> patch_spv,
|
||||
bool is_patched) {
|
||||
shader_dump_list.emplace_back(name, l_stage, module, std::vector<u32>{spv.begin(), spv.end()},
|
||||
std::vector<u32>{raw_code.begin(), raw_code.end()},
|
||||
std::vector<u32>{patch_spv.begin(), patch_spv.end()}, is_patched);
|
||||
}
|
||||
|
@ -11,8 +11,7 @@
|
||||
#include <queue>
|
||||
|
||||
#include "common/types.h"
|
||||
#include "video_core/amdgpu/liverpool.h"
|
||||
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||
#include "video_core/renderer_vulkan/vk_graphics_pipeline.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
@ -30,11 +29,14 @@ namespace Core::Devtools {
|
||||
class Layer;
|
||||
namespace Widget {
|
||||
class FrameGraph;
|
||||
}
|
||||
class ShaderList;
|
||||
} // namespace Widget
|
||||
} // namespace Core::Devtools
|
||||
|
||||
namespace DebugStateType {
|
||||
|
||||
extern bool showing_debug_menu_bar;
|
||||
|
||||
enum class QueueType {
|
||||
dcb = 0,
|
||||
ccb = 1,
|
||||
@ -49,12 +51,16 @@ struct QueueDump {
|
||||
uintptr_t base_addr;
|
||||
};
|
||||
|
||||
struct ShaderDump {
|
||||
struct PipelineShaderProgramDump {
|
||||
std::string name;
|
||||
u64 hash;
|
||||
Vulkan::Liverpool::ShaderProgram user_data{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
|
||||
struct ComputerShaderDump {
|
||||
struct PipelineComputerProgramDump {
|
||||
std::string name;
|
||||
u64 hash;
|
||||
Vulkan::Liverpool::ComputeProgram cs_program{};
|
||||
std::vector<u32> code{};
|
||||
};
|
||||
@ -63,8 +69,8 @@ struct RegDump {
|
||||
bool is_compute{false};
|
||||
static constexpr size_t MaxShaderStages = 5;
|
||||
Vulkan::Liverpool::Regs regs{};
|
||||
std::array<ShaderDump, MaxShaderStages> stages{};
|
||||
ComputerShaderDump cs_data{};
|
||||
std::array<PipelineShaderProgramDump, MaxShaderStages> stages{};
|
||||
PipelineComputerProgramDump cs_data{};
|
||||
};
|
||||
|
||||
struct FrameDump {
|
||||
@ -73,9 +79,61 @@ struct FrameDump {
|
||||
std::unordered_map<uintptr_t, RegDump> regs; // address -> reg dump
|
||||
};
|
||||
|
||||
struct ShaderDump {
|
||||
std::string name;
|
||||
Shader::LogicalStage l_stage;
|
||||
vk::ShaderModule module;
|
||||
|
||||
std::vector<u32> spv;
|
||||
std::vector<u32> isa;
|
||||
|
||||
std::vector<u32> patch_spv;
|
||||
std::string patch_source{};
|
||||
|
||||
bool loaded_data = false;
|
||||
bool is_patched = false;
|
||||
std::string cache_spv_disasm{};
|
||||
std::string cache_isa_disasm{};
|
||||
std::string cache_patch_disasm{};
|
||||
|
||||
ShaderDump(std::string name, Shader::LogicalStage l_stage, vk::ShaderModule module,
|
||||
std::vector<u32> spv, std::vector<u32> isa, std::vector<u32> patch_spv,
|
||||
bool is_patched)
|
||||
: name(std::move(name)), l_stage(l_stage), module(module), spv(std::move(spv)),
|
||||
isa(std::move(isa)), patch_spv(std::move(patch_spv)), is_patched(is_patched) {}
|
||||
|
||||
ShaderDump(const ShaderDump& other) = delete;
|
||||
ShaderDump(ShaderDump&& other) noexcept
|
||||
: name{std::move(other.name)}, l_stage(other.l_stage), module{std::move(other.module)},
|
||||
spv{std::move(other.spv)}, isa{std::move(other.isa)},
|
||||
patch_spv{std::move(other.patch_spv)}, patch_source{std::move(other.patch_source)},
|
||||
cache_spv_disasm{std::move(other.cache_spv_disasm)},
|
||||
cache_isa_disasm{std::move(other.cache_isa_disasm)},
|
||||
cache_patch_disasm{std::move(other.cache_patch_disasm)} {}
|
||||
ShaderDump& operator=(const ShaderDump& other) = delete;
|
||||
ShaderDump& operator=(ShaderDump&& other) noexcept {
|
||||
if (this == &other)
|
||||
return *this;
|
||||
name = std::move(other.name);
|
||||
l_stage = other.l_stage;
|
||||
module = std::move(other.module);
|
||||
spv = std::move(other.spv);
|
||||
isa = std::move(other.isa);
|
||||
patch_spv = std::move(other.patch_spv);
|
||||
patch_source = std::move(other.patch_source);
|
||||
cache_spv_disasm = std::move(other.cache_spv_disasm);
|
||||
cache_isa_disasm = std::move(other.cache_isa_disasm);
|
||||
cache_patch_disasm = std::move(other.cache_patch_disasm);
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
class DebugStateImpl {
|
||||
friend class Core::Devtools::Layer;
|
||||
friend class Core::Devtools::Widget::FrameGraph;
|
||||
friend class Core::Devtools::Widget::ShaderList;
|
||||
|
||||
std::queue<std::string> debug_message_popup;
|
||||
|
||||
std::mutex guest_threads_mutex{};
|
||||
std::vector<ThreadID> guest_threads{};
|
||||
@ -94,9 +152,12 @@ class DebugStateImpl {
|
||||
std::shared_mutex frame_dump_list_mutex;
|
||||
std::vector<FrameDump> frame_dump_list{};
|
||||
|
||||
std::queue<std::string> debug_message_popup;
|
||||
std::vector<ShaderDump> shader_dump_list{};
|
||||
|
||||
public:
|
||||
float Framerate = 1.0f / 60.0f;
|
||||
float FrameDeltaTime;
|
||||
|
||||
void ShowDebugMessage(std::string message) {
|
||||
if (message.empty()) {
|
||||
return;
|
||||
@ -104,6 +165,10 @@ public:
|
||||
debug_message_popup.push(std::move(message));
|
||||
}
|
||||
|
||||
bool& IsShowingDebugMenuBar() {
|
||||
return showing_debug_menu_bar;
|
||||
}
|
||||
|
||||
void AddCurrentThreadToGuestList();
|
||||
|
||||
void RemoveCurrentThreadFromGuestList();
|
||||
@ -151,7 +216,17 @@ public:
|
||||
void PushQueueDump(QueueDump dump);
|
||||
|
||||
void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||
const AmdGpu::Liverpool::Regs& regs, bool is_compute = false);
|
||||
const AmdGpu::Liverpool::Regs& regs);
|
||||
using CsState = AmdGpu::Liverpool::ComputeProgram;
|
||||
void PushRegsDumpCompute(uintptr_t base_addr, uintptr_t header_addr, const CsState& cs_state);
|
||||
|
||||
void CollectShader(const std::string& name, Shader::LogicalStage l_stage,
|
||||
vk::ShaderModule module, std::span<const u32> spv,
|
||||
std::span<const u32> raw_code, std::span<const u32> patch_spv,
|
||||
bool is_patched);
|
||||
|
||||
private:
|
||||
std::optional<RegDump*> GetRegDump(uintptr_t base_addr, uintptr_t header_addr);
|
||||
};
|
||||
} // namespace DebugStateType
|
||||
|
||||
|
12
src/core/devices/base_device.cpp
Normal file
12
src/core/devices/base_device.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "base_device.h"
|
||||
|
||||
namespace Core::Devices {
|
||||
|
||||
BaseDevice::BaseDevice() = default;
|
||||
|
||||
BaseDevice::~BaseDevice() = default;
|
||||
|
||||
} // namespace Core::Devices
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user