mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 12:34:17 +01:00
Merge branch 'refs/heads/main' into loadaudio
# Conflicts: # src/gui/GeneralSettings2.cpp
This commit is contained in:
commit
ac5c44d2cf
@ -15,6 +15,7 @@ BinPackArguments: true
|
|||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
AfterCaseLabel: true
|
AfterCaseLabel: true
|
||||||
|
AfterClass: true
|
||||||
AfterControlStatement: Always
|
AfterControlStatement: Always
|
||||||
AfterEnum: true
|
AfterEnum: true
|
||||||
AfterExternBlock: true
|
AfterExternBlock: true
|
||||||
|
9
.github/getversion.cpp
vendored
9
.github/getversion.cpp
vendored
@ -1,9 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include "./../src/Common/version.h"
|
|
||||||
|
|
||||||
// output current Cemu version for CI workflow. Do not modify
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
printf("%d.%d", EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR);
|
|
||||||
return 0;
|
|
||||||
}
|
|
91
.github/workflows/build.yml
vendored
91
.github/workflows/build.yml
vendored
@ -3,10 +3,10 @@ name: Build Cemu
|
|||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
inputs:
|
inputs:
|
||||||
deploymode:
|
next_version_major:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
experimentalversion:
|
next_version_minor:
|
||||||
required: false
|
required: false
|
||||||
type: string
|
type: string
|
||||||
|
|
||||||
@ -24,30 +24,17 @@ jobs:
|
|||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: "Fetch full history for vcpkg submodule"
|
- name: Setup release mode parameters
|
||||||
run: |
|
|
||||||
cd dependencies/vcpkg
|
|
||||||
git fetch --unshallow
|
|
||||||
|
|
||||||
- name: Setup release mode parameters (for deploy)
|
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
||||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||||
echo "Build mode is release"
|
echo "Build mode is release"
|
||||||
|
|
||||||
- name: Setup debug mode parameters (for continous build)
|
- name: Setup build flags for version
|
||||||
if: ${{ inputs.deploymode != 'release' }}
|
if: ${{ inputs.next_version_major != '' }}
|
||||||
run: |
|
run: |
|
||||||
echo "BUILD_MODE=debug" >> $GITHUB_ENV
|
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" >> $GITHUB_ENV
|
||||||
echo "Build mode is debug"
|
|
||||||
|
|
||||||
- name: Setup version for experimental
|
|
||||||
if: ${{ inputs.experimentalversion != '' }}
|
|
||||||
run: |
|
|
||||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
|
||||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: "Install system dependencies"
|
- name: "Install system dependencies"
|
||||||
run: |
|
run: |
|
||||||
@ -86,12 +73,10 @@ jobs:
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: mv bin/Cemu_release bin/Cemu
|
run: mv bin/Cemu_release bin/Cemu
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
with:
|
with:
|
||||||
name: cemu-bin-linux-x64
|
name: cemu-bin-linux-x64
|
||||||
path: ./bin/Cemu
|
path: ./bin/Cemu
|
||||||
@ -133,29 +118,17 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
|
|
||||||
- name: "Fetch full history for vcpkg submodule"
|
- name: Setup release mode parameters
|
||||||
run: |
|
|
||||||
cd dependencies/vcpkg
|
|
||||||
git fetch --unshallow
|
|
||||||
|
|
||||||
- name: Setup release mode parameters (for deploy)
|
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "BUILD_MODE=release" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILD_MODE=release" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "Build mode is release"
|
echo "Build mode is release"
|
||||||
|
|
||||||
- name: Setup debug mode parameters (for continous build)
|
- name: Setup build flags for version
|
||||||
if: ${{ inputs.deploymode != 'release' }}
|
if: ${{ inputs.next_version_major != '' }}
|
||||||
run: |
|
run: |
|
||||||
echo "BUILD_MODE=debug" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||||
echo "BUILD_FLAGS=" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "Build mode is debug"
|
|
||||||
- name: Setup version for experimental
|
|
||||||
if: ${{ inputs.experimentalversion != '' }}
|
|
||||||
run: |
|
|
||||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
|
||||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append
|
|
||||||
|
|
||||||
- name: "Setup cmake"
|
- name: "Setup cmake"
|
||||||
uses: jwlawson/actions-setup-cmake@v2
|
uses: jwlawson/actions-setup-cmake@v2
|
||||||
@ -194,52 +167,45 @@ jobs:
|
|||||||
cmake --build . --config ${{ env.BUILD_MODE }}
|
cmake --build . --config ${{ env.BUILD_MODE }}
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: Rename-Item bin/Cemu_release.exe Cemu.exe
|
run: Rename-Item bin/Cemu_release.exe Cemu.exe
|
||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
with:
|
with:
|
||||||
name: cemu-bin-windows-x64
|
name: cemu-bin-windows-x64
|
||||||
path: ./bin/Cemu.exe
|
path: ./bin/Cemu.exe
|
||||||
|
|
||||||
build-macos:
|
build-macos:
|
||||||
runs-on: macos-12
|
runs-on: macos-14
|
||||||
steps:
|
steps:
|
||||||
- name: "Checkout repo"
|
- name: "Checkout repo"
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
submodules: "recursive"
|
submodules: "recursive"
|
||||||
|
|
||||||
- name: "Fetch full history for vcpkg submodule"
|
- name: Setup release mode parameters
|
||||||
run: |
|
|
||||||
cd dependencies/vcpkg
|
|
||||||
git fetch --unshallow
|
|
||||||
|
|
||||||
- name: Setup release mode parameters (for deploy)
|
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: |
|
run: |
|
||||||
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
echo "BUILD_MODE=release" >> $GITHUB_ENV
|
||||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
||||||
echo "Build mode is release"
|
echo "Build mode is release"
|
||||||
- name: Setup debug mode parameters (for continous build)
|
|
||||||
if: ${{ inputs.deploymode != 'release' }}
|
|
||||||
run: |
|
|
||||||
echo "BUILD_MODE=debug" >> $GITHUB_ENV
|
|
||||||
echo "BUILD_FLAGS=" >> $GITHUB_ENV
|
|
||||||
echo "Build mode is debug"
|
|
||||||
|
|
||||||
- name: Setup version for experimental
|
- name: Setup build flags for version
|
||||||
if: ${{ inputs.experimentalversion != '' }}
|
if: ${{ inputs.next_version_major != '' }}
|
||||||
run: |
|
run: |
|
||||||
echo "[INFO] Experimental version ${{ inputs.experimentalversion }}"
|
echo "[INFO] Version ${{ inputs.next_version_major }}.${{ inputs.next_version_minor }}"
|
||||||
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEXPERIMENTAL_VERSION=${{ inputs.experimentalversion }}" >> $GITHUB_ENV
|
echo "BUILD_FLAGS=${{ env.BUILD_FLAGS }} -DEMULATOR_VERSION_MAJOR=${{ inputs.next_version_major }} -DEMULATOR_VERSION_MINOR=${{ inputs.next_version_minor }}" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: "Install system dependencies"
|
- name: "Install system dependencies"
|
||||||
run: |
|
run: |
|
||||||
brew update
|
brew update
|
||||||
brew install llvm@15 ninja nasm molten-vk automake libtool
|
brew install ninja nasm automake libtool
|
||||||
|
|
||||||
|
- name: "Install molten-vk"
|
||||||
|
run: |
|
||||||
|
curl -L -O https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.9/MoltenVK-macos.tar
|
||||||
|
tar xf MoltenVK-macos.tar
|
||||||
|
sudo mkdir -p /usr/local/lib
|
||||||
|
sudo cp MoltenVK/MoltenVK/dynamic/dylib/macOS/libMoltenVK.dylib /usr/local/lib
|
||||||
|
|
||||||
- name: "Setup cmake"
|
- name: "Setup cmake"
|
||||||
uses: jwlawson/actions-setup-cmake@v2
|
uses: jwlawson/actions-setup-cmake@v2
|
||||||
@ -270,9 +236,8 @@ jobs:
|
|||||||
cd build
|
cd build
|
||||||
cmake .. ${{ env.BUILD_FLAGS }} \
|
cmake .. ${{ env.BUILD_FLAGS }} \
|
||||||
-DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} \
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_MODE }} \
|
||||||
|
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||||
-DMACOS_BUNDLE=ON \
|
-DMACOS_BUNDLE=ON \
|
||||||
-DCMAKE_C_COMPILER=/usr/local/opt/llvm@15/bin/clang \
|
|
||||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@15/bin/clang++ \
|
|
||||||
-G Ninja
|
-G Ninja
|
||||||
|
|
||||||
- name: "Build Cemu"
|
- name: "Build Cemu"
|
||||||
@ -280,7 +245,6 @@ jobs:
|
|||||||
cmake --build build
|
cmake --build build
|
||||||
|
|
||||||
- name: Prepare artifact
|
- name: Prepare artifact
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
run: |
|
run: |
|
||||||
mkdir bin/Cemu_app
|
mkdir bin/Cemu_app
|
||||||
mv bin/Cemu_release.app bin/Cemu_app/Cemu.app
|
mv bin/Cemu_release.app bin/Cemu_app/Cemu.app
|
||||||
@ -294,7 +258,6 @@ jobs:
|
|||||||
|
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
if: ${{ inputs.deploymode == 'release' }}
|
|
||||||
with:
|
with:
|
||||||
name: cemu-bin-macos-x64
|
name: cemu-bin-macos-x64
|
||||||
path: ./bin/Cemu.dmg
|
path: ./bin/Cemu.dmg
|
||||||
|
3
.github/workflows/build_check.yml
vendored
3
.github/workflows/build_check.yml
vendored
@ -16,6 +16,3 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
with:
|
|
||||||
deploymode: release
|
|
||||||
experimentalversion: 999999
|
|
||||||
|
@ -1,20 +1,83 @@
|
|||||||
name: Deploy experimental release
|
name: Deploy experimental release
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
changelog0:
|
||||||
|
description: 'Enter the changelog lines for this release. Each line is a feature / bullet point. Do not use dash.'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
changelog1:
|
||||||
|
description: 'Feature 2'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog2:
|
||||||
|
description: 'Feature 3'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog3:
|
||||||
|
description: 'Feature 4'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog4:
|
||||||
|
description: 'Feature 5'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog5:
|
||||||
|
description: 'Feature 6'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog6:
|
||||||
|
description: 'Feature 7'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog7:
|
||||||
|
description: 'Feature 8'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog8:
|
||||||
|
description: 'Feature 9'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
changelog9:
|
||||||
|
description: 'Feature 10'
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
calculate-version:
|
||||||
|
name: Calculate Version
|
||||||
|
uses: ./.github/workflows/determine_release_version.yml
|
||||||
call-release-build:
|
call-release-build:
|
||||||
uses: ./.github/workflows/build.yml
|
uses: ./.github/workflows/build.yml
|
||||||
|
needs: calculate-version
|
||||||
with:
|
with:
|
||||||
deploymode: release
|
next_version_major: ${{ needs.calculate-version.outputs.next_version_major }}
|
||||||
experimentalversion: ${{ github.run_number }}
|
next_version_minor: ${{ needs.calculate-version.outputs.next_version_minor }}
|
||||||
deploy:
|
deploy:
|
||||||
name: Deploy experimental release
|
name: Deploy experimental release
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
needs: call-release-build
|
needs: [call-release-build, calculate-version]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate changelog
|
||||||
|
id: generate_changelog
|
||||||
|
run: |
|
||||||
|
CHANGELOG=""
|
||||||
|
if [ -n "${{ github.event.inputs.changelog0 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog0 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog1 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog1 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog2 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog2 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog3 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog3 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog4 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog4 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog5 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog5 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog6 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog6 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog7 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog7 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog8 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog8 }}\n"; fi
|
||||||
|
if [ -n "${{ github.event.inputs.changelog9 }}" ]; then CHANGELOG="$CHANGELOG- ${{ github.event.inputs.changelog9 }}\n"; fi
|
||||||
|
echo -e "$CHANGELOG"
|
||||||
|
echo "RELEASE_BODY=$CHANGELOG" >> $GITHUB_ENV
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: cemu-bin-linux-x64
|
name: cemu-bin-linux-x64
|
||||||
@ -40,15 +103,13 @@ jobs:
|
|||||||
mkdir upload
|
mkdir upload
|
||||||
sudo apt install zip
|
sudo apt install zip
|
||||||
|
|
||||||
- name: Get version
|
- name: Set version dependent vars
|
||||||
run: |
|
run: |
|
||||||
echo "Experimental version: ${{ github.run_number }}"
|
echo "Version: ${{ needs.calculate-version.outputs.next_version }}"
|
||||||
ls
|
echo "CEMU_FOLDER_NAME=Cemu_${{ needs.calculate-version.outputs.next_version }}"
|
||||||
gcc -o getversion .github/getversion.cpp
|
echo "CEMU_VERSION=${{ needs.calculate-version.outputs.next_version }}"
|
||||||
./getversion
|
echo "CEMU_FOLDER_NAME=Cemu_${{ needs.calculate-version.outputs.next_version }}" >> $GITHUB_ENV
|
||||||
echo "Cemu CI version: $(./getversion)"
|
echo "CEMU_VERSION=${{ needs.calculate-version.outputs.next_version }}" >> $GITHUB_ENV
|
||||||
echo "CEMU_FOLDER_NAME=Cemu_$(./getversion)-${{ github.run_number }}" >> $GITHUB_ENV
|
|
||||||
echo "CEMU_VERSION=$(./getversion)-${{ github.run_number }}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Create release from windows-bin
|
- name: Create release from windows-bin
|
||||||
run: |
|
run: |
|
||||||
@ -83,4 +144,8 @@ jobs:
|
|||||||
wget -O ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.15.0/ghr_v0.15.0_linux_amd64.tar.gz
|
wget -O ghr.tar.gz https://github.com/tcnksm/ghr/releases/download/v0.15.0/ghr_v0.15.0_linux_amd64.tar.gz
|
||||||
tar xvzf ghr.tar.gz; rm ghr.tar.gz
|
tar xvzf ghr.tar.gz; rm ghr.tar.gz
|
||||||
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
|
echo "[INFO] Release tag: v${{ env.CEMU_VERSION }}"
|
||||||
ghr_v0.15.0_linux_amd64/ghr -prerelease -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }} (Experimental)" -b "Cemu experimental release" "v${{ env.CEMU_VERSION }}" ./upload
|
CHANGELOG_UNESCAPED=$(printf "%s\n" "${{ env.RELEASE_BODY }}" | sed 's/\\n/\n/g')
|
||||||
|
RELEASE_BODY=$(printf "%s\n%s" \
|
||||||
|
"**Changelog:**" \
|
||||||
|
"$CHANGELOG_UNESCAPED")
|
||||||
|
ghr_v0.15.0_linux_amd64/ghr -draft -t ${{ secrets.GITHUB_TOKEN }} -n "Cemu ${{ env.CEMU_VERSION }}" -b "$RELEASE_BODY" "v${{ env.CEMU_VERSION }}" ./upload
|
||||||
|
74
.github/workflows/determine_release_version.yml
vendored
Normal file
74
.github/workflows/determine_release_version.yml
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
name: Calculate Next Version from release history
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
workflow_call:
|
||||||
|
outputs:
|
||||||
|
next_version:
|
||||||
|
description: "The next semantic version"
|
||||||
|
value: ${{ jobs.calculate-version.outputs.next_version }}
|
||||||
|
next_version_major:
|
||||||
|
description: "The next semantic version (major)"
|
||||||
|
value: ${{ jobs.calculate-version.outputs.next_version_major }}
|
||||||
|
next_version_minor:
|
||||||
|
description: "The next semantic version (minor)"
|
||||||
|
value: ${{ jobs.calculate-version.outputs.next_version_minor }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
calculate-version:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
next_version: ${{ steps.calculate_next_version.outputs.next_version }}
|
||||||
|
next_version_major: ${{ steps.calculate_next_version.outputs.next_version_major }}
|
||||||
|
next_version_minor: ${{ steps.calculate_next_version.outputs.next_version_minor }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Get all releases
|
||||||
|
id: get_all_releases
|
||||||
|
run: |
|
||||||
|
# Fetch all releases and check for API errors
|
||||||
|
RESPONSE=$(curl -s -o response.json -w "%{http_code}" "https://api.github.com/repos/${{ github.repository }}/releases?per_page=100")
|
||||||
|
if [ "$RESPONSE" -ne 200 ]; then
|
||||||
|
echo "Failed to fetch releases. HTTP status: $RESPONSE"
|
||||||
|
cat response.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract and sort tags
|
||||||
|
ALL_TAGS=$(jq -r '.[].tag_name' response.json | grep -E '^v[0-9]+\.[0-9]+(-[0-9]+)?$' | sed 's/-.*//' | sort -V | tail -n 1)
|
||||||
|
|
||||||
|
# Exit if no tags were found
|
||||||
|
if [ -z "$ALL_TAGS" ]; then
|
||||||
|
echo "No valid tags found."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "::set-output name=tag::$ALL_TAGS"
|
||||||
|
# echo "tag=$ALL_TAGS" >> $GITHUB_STATE
|
||||||
|
|
||||||
|
- name: Calculate next semver minor
|
||||||
|
id: calculate_next_version
|
||||||
|
run: |
|
||||||
|
LATEST_VERSION=${{ steps.get_all_releases.outputs.tag }}
|
||||||
|
|
||||||
|
# strip 'v' prefix and split into major.minor
|
||||||
|
LATEST_VERSION=${LATEST_VERSION//v/}
|
||||||
|
IFS='.' read -r -a VERSION_PARTS <<< "$LATEST_VERSION"
|
||||||
|
|
||||||
|
MAJOR=${VERSION_PARTS[0]}
|
||||||
|
MINOR=${VERSION_PARTS[1]}
|
||||||
|
|
||||||
|
# increment the minor version
|
||||||
|
MINOR=$((MINOR + 1))
|
||||||
|
|
||||||
|
NEXT_VERSION="${MAJOR}.${MINOR}"
|
||||||
|
|
||||||
|
echo "Major: $MAJOR"
|
||||||
|
echo "Minor: $MINOR"
|
||||||
|
|
||||||
|
echo "Next version: $NEXT_VERSION"
|
||||||
|
echo "::set-output name=next_version::$NEXT_VERSION"
|
||||||
|
echo "::set-output name=next_version_major::$MAJOR"
|
||||||
|
echo "::set-output name=next_version_minor::$MINOR"
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -9,10 +9,12 @@
|
|||||||
[submodule "dependencies/vcpkg"]
|
[submodule "dependencies/vcpkg"]
|
||||||
path = dependencies/vcpkg
|
path = dependencies/vcpkg
|
||||||
url = https://github.com/microsoft/vcpkg
|
url = https://github.com/microsoft/vcpkg
|
||||||
shallow = true
|
shallow = false
|
||||||
[submodule "dependencies/Vulkan-Headers"]
|
[submodule "dependencies/Vulkan-Headers"]
|
||||||
path = dependencies/Vulkan-Headers
|
path = dependencies/Vulkan-Headers
|
||||||
url = https://github.com/KhronosGroup/Vulkan-Headers
|
url = https://github.com/KhronosGroup/Vulkan-Headers
|
||||||
|
shallow = true
|
||||||
[submodule "dependencies/imgui"]
|
[submodule "dependencies/imgui"]
|
||||||
path = dependencies/imgui
|
path = dependencies/imgui
|
||||||
url = https://github.com/ocornut/imgui
|
url = https://github.com/ocornut/imgui
|
||||||
|
shallow = true
|
||||||
|
52
BUILD.md
52
BUILD.md
@ -16,11 +16,11 @@
|
|||||||
- [Compiling Errors](#compiling-errors)
|
- [Compiling Errors](#compiling-errors)
|
||||||
- [Building Errors](#building-errors)
|
- [Building Errors](#building-errors)
|
||||||
- [macOS](#macos)
|
- [macOS](#macos)
|
||||||
- [On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used](#on-apple-silicon-macs-rosetta-2-and-the-x86_64-version-of-homebrew-must-be-used)
|
|
||||||
- [Installing brew](#installing-brew)
|
- [Installing brew](#installing-brew)
|
||||||
- [Installing Dependencies](#installing-dependencies)
|
- [Installing Tool Dependencies](#installing-tool-dependencies)
|
||||||
- [Build Cemu using CMake and Clang](#build-cemu-using-cmake-and-clang)
|
- [Installing Library Dependencies](#installing-library-dependencies)
|
||||||
- [Updating Cemu and source code](#updating-cemu-and-source-code)
|
- [Build Cemu using CMake](#build-cemu-using-cmake)
|
||||||
|
- [Updating Cemu and source code](#updating-cemu-and-source-code)
|
||||||
|
|
||||||
## Windows
|
## Windows
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ At Step 3 in [Build Cemu using cmake and clang](#build-cemu-using-cmake-and-clan
|
|||||||
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-15 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-15 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`
|
`cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/bin/clang-15 -DCMAKE_CXX_COMPILER=/usr/bin/clang++-15 -G Ninja -DCMAKE_MAKE_PROGRAM=/usr/bin/ninja`
|
||||||
|
|
||||||
#### For Fedora and derivatives:
|
#### For Fedora and derivatives:
|
||||||
`sudo dnf install clang cmake cubeb-devel freeglut-devel git glm-devel gtk3-devel kernel-headers libgcrypt-devel libsecret-devel libtool libusb1-devel llvm nasm ninja-build perl-core systemd-devel zlib-devel`
|
`sudo dnf install clang cmake cubeb-devel freeglut-devel git glm-devel gtk3-devel kernel-headers libgcrypt-devel libsecret-devel libtool libusb1-devel llvm nasm ninja-build perl-core systemd-devel zlib-devel zlib-static`
|
||||||
|
|
||||||
### Build Cemu
|
### Build Cemu
|
||||||
|
|
||||||
@ -141,31 +141,41 @@ If you are getting a different error than any of the errors listed above, you ma
|
|||||||
|
|
||||||
## macOS
|
## macOS
|
||||||
|
|
||||||
To compile Cemu, a recent enough compiler and STL with C++20 support is required! LLVM 13 and
|
To compile Cemu, a recent enough compiler and STL with C++20 support is required! LLVM 13 and below
|
||||||
below, built in LLVM, and Xcode LLVM don't support the C++20 feature set required. The OpenGL graphics
|
don't support the C++20 feature set required, so either install LLVM from Homebrew or make sure that
|
||||||
API isn't support on macOS, Vulkan must be used. Additionally Vulkan must be used through the
|
you have a recent enough version of Xcode. Xcode 15 is known to work. The OpenGL graphics API isn't
|
||||||
Molten-VK compatibility layer
|
supported on macOS, so Vulkan must be used through the Molten-VK compatibility layer.
|
||||||
|
|
||||||
### On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used
|
|
||||||
|
|
||||||
You can skip this section if you have an Intel Mac. Every time you compile, you need to perform steps 2.
|
|
||||||
|
|
||||||
1. `softwareupdate --install-rosetta` # Install Rosetta 2 if you don't have it. This only has to be done once
|
|
||||||
2. `arch -x86_64 zsh` # run an x64 shell
|
|
||||||
|
|
||||||
### Installing brew
|
### Installing brew
|
||||||
|
|
||||||
1. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
1. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
||||||
2. `eval "$(/usr/local/Homebrew/bin/brew shellenv)"` # set x86_64 brew env
|
2. Set up the Homebrew shell environment:
|
||||||
|
1. **On an Intel Mac:** `eval "$(/usr/local/Homebrew/bin/brew shellenv)"`
|
||||||
|
2. **On an Apple Silicon Mac:** eval `"$(/opt/homebrew/bin/brew shellenv)"`
|
||||||
|
|
||||||
### Installing Dependencies
|
### Installing Tool Dependencies
|
||||||
|
|
||||||
`brew install boost git cmake llvm ninja nasm molten-vk automake libtool`
|
The native versions of these can be used regardless of what type of Mac you have.
|
||||||
|
|
||||||
|
`brew install git cmake ninja nasm automake libtool`
|
||||||
|
|
||||||
|
### Installing Library Dependencies
|
||||||
|
|
||||||
|
**On Apple Silicon Macs, Rosetta 2 and the x86_64 version of Homebrew must be used to install these dependencies:**
|
||||||
|
1. `softwareupdate --install-rosetta` # Install Rosetta 2 if you don't have it. This only has to be done once
|
||||||
|
2. `arch -x86_64 zsh` # run an x64 shell
|
||||||
|
3. `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`
|
||||||
|
4. `eval "$(/usr/local/Homebrew/bin/brew shellenv)"`
|
||||||
|
|
||||||
|
Then install the dependencies:
|
||||||
|
|
||||||
|
`brew install boost molten-vk`
|
||||||
|
|
||||||
|
### Build Cemu using CMake
|
||||||
|
|
||||||
### Build Cemu using CMake and Clang
|
|
||||||
1. `git clone --recursive https://github.com/cemu-project/Cemu`
|
1. `git clone --recursive https://github.com/cemu-project/Cemu`
|
||||||
2. `cd Cemu`
|
2. `cd Cemu`
|
||||||
3. `cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_C_COMPILER=/usr/local/opt/llvm/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/opt/llvm/bin/clang++ -G Ninja`
|
3. `cmake -S . -B build -DCMAKE_BUILD_TYPE=release -DCMAKE_OSX_ARCHITECTURES=x86_64 -G Ninja`
|
||||||
4. `cmake --build build`
|
4. `cmake --build build`
|
||||||
5. You should now have a Cemu executable file in the /bin folder, which you can run using `./bin/Cemu_release`.
|
5. You should now have a Cemu executable file in the /bin folder, which you can run using `./bin/Cemu_release`.
|
||||||
|
|
||||||
|
@ -2,20 +2,39 @@ cmake_minimum_required(VERSION 3.21.1)
|
|||||||
|
|
||||||
option(ENABLE_VCPKG "Enable the vcpkg package manager" ON)
|
option(ENABLE_VCPKG "Enable the vcpkg package manager" ON)
|
||||||
option(MACOS_BUNDLE "The executable when built on macOS will be created as an application bundle" OFF)
|
option(MACOS_BUNDLE "The executable when built on macOS will be created as an application bundle" OFF)
|
||||||
set(EXPERIMENTAL_VERSION "" CACHE STRING "") # used by CI script to set experimental version
|
|
||||||
|
|
||||||
if (EXPERIMENTAL_VERSION)
|
# used by CI script to set version:
|
||||||
add_definitions(-DEMULATOR_VERSION_MINOR=${EXPERIMENTAL_VERSION})
|
set(EMULATOR_VERSION_MAJOR "0" CACHE STRING "")
|
||||||
execute_process(
|
set(EMULATOR_VERSION_MINOR "0" CACHE STRING "")
|
||||||
COMMAND git log --format=%h -1
|
set(EMULATOR_VERSION_PATCH "0" CACHE STRING "")
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
|
||||||
OUTPUT_VARIABLE GIT_HASH
|
execute_process(
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
COMMAND git log --format=%h -1
|
||||||
)
|
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||||
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
|
OUTPUT_VARIABLE GIT_HASH
|
||||||
endif()
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
add_definitions(-DEMULATOR_HASH=${GIT_HASH})
|
||||||
|
|
||||||
if (ENABLE_VCPKG)
|
if (ENABLE_VCPKG)
|
||||||
|
# check if vcpkg is shallow and unshallow it if necessary
|
||||||
|
execute_process(
|
||||||
|
COMMAND git rev-parse --is-shallow-repository
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/dependencies/vcpkg
|
||||||
|
OUTPUT_VARIABLE is_vcpkg_shallow
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(is_vcpkg_shallow STREQUAL "true")
|
||||||
|
message(STATUS "vcpkg is shallow. Unshallowing it now...")
|
||||||
|
execute_process(
|
||||||
|
COMMAND git fetch --unshallow
|
||||||
|
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/dependencies/vcpkg"
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux")
|
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/dependencies/vcpkg_overlay_ports_linux")
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
@ -44,6 +63,10 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||||||
|
|
||||||
add_compile_definitions($<$<CONFIG:Debug>:CEMU_DEBUG_ASSERT>) # if build type is debug, set CEMU_DEBUG_ASSERT
|
add_compile_definitions($<$<CONFIG:Debug>:CEMU_DEBUG_ASSERT>) # if build type is debug, set CEMU_DEBUG_ASSERT
|
||||||
|
|
||||||
|
add_definitions(-DEMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR})
|
||||||
|
add_definitions(-DEMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR})
|
||||||
|
add_definitions(-DEMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH})
|
||||||
|
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
# enable link time optimization for release builds
|
# enable link time optimization for release builds
|
||||||
@ -69,6 +92,7 @@ endif()
|
|||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
enable_language(OBJC OBJCXX)
|
enable_language(OBJC OBJCXX)
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (UNIX AND NOT APPLE)
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +0,0 @@
|
|||||||
If you plan to transfer the shader cache to a different PC or Cemu installation you only need to copy the 'transferable' directory.
|
|
12
dependencies/ih264d/CMakeLists.txt
vendored
12
dependencies/ih264d/CMakeLists.txt
vendored
@ -117,7 +117,13 @@ add_library (ih264d
|
|||||||
"decoder/ivd.h"
|
"decoder/ivd.h"
|
||||||
)
|
)
|
||||||
|
|
||||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
if (CMAKE_OSX_ARCHITECTURES)
|
||||||
|
set(IH264D_ARCHITECTURE ${CMAKE_OSX_ARCHITECTURES})
|
||||||
|
else()
|
||||||
|
set(IH264D_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (IH264D_ARCHITECTURE STREQUAL "x86_64" OR IH264D_ARCHITECTURE STREQUAL "amd64" OR IH264D_ARCHITECTURE STREQUAL "AMD64")
|
||||||
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
||||||
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
||||||
target_sources(ih264d PRIVATE
|
target_sources(ih264d PRIVATE
|
||||||
@ -140,7 +146,7 @@ target_sources(ih264d PRIVATE
|
|||||||
"decoder/x86/ih264d_function_selector_sse42.c"
|
"decoder/x86/ih264d_function_selector_sse42.c"
|
||||||
"decoder/x86/ih264d_function_selector_ssse3.c"
|
"decoder/x86/ih264d_function_selector_ssse3.c"
|
||||||
)
|
)
|
||||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
elseif(IH264D_ARCHITECTURE STREQUAL "aarch64" OR IH264D_ARCHITECTURE STREQUAL "arm64")
|
||||||
enable_language( C CXX ASM )
|
enable_language( C CXX ASM )
|
||||||
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
||||||
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
||||||
@ -178,7 +184,7 @@ target_sources(ih264d PRIVATE
|
|||||||
)
|
)
|
||||||
target_compile_options(ih264d PRIVATE -DARMV8)
|
target_compile_options(ih264d PRIVATE -DARMV8)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "ih264d unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
message(FATAL_ERROR "ih264d unknown architecture: ${IH264D_ARCHITECTURE}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
2
dependencies/vcpkg
vendored
2
dependencies/vcpkg
vendored
@ -1 +1 @@
|
|||||||
Subproject commit cbf4a6641528cee6f172328984576f51698de726
|
Subproject commit a4275b7eee79fb24ec2e135481ef5fce8b41c339
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/SDL2Config.cmake.in b/SDL2Config.cmake.in
|
|
||||||
index cc8bcf26d..ead829767 100644
|
|
||||||
--- a/SDL2Config.cmake.in
|
|
||||||
+++ b/SDL2Config.cmake.in
|
|
||||||
@@ -35,7 +35,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/sdlfind.cmake")
|
|
||||||
|
|
||||||
set(SDL_ALSA @SDL_ALSA@)
|
|
||||||
set(SDL_ALSA_SHARED @SDL_ALSA_SHARED@)
|
|
||||||
-if(SDL_ALSA AND NOT SDL_ALSA_SHARED AND TARGET SDL2::SDL2-static)
|
|
||||||
+if(SDL_ALSA)
|
|
||||||
sdlFindALSA()
|
|
||||||
endif()
|
|
||||||
unset(SDL_ALSA)
|
|
13
dependencies/vcpkg_overlay_ports/sdl2/deps.patch
vendored
13
dependencies/vcpkg_overlay_ports/sdl2/deps.patch
vendored
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
|
|
||||||
index 65a98efbe..2f99f28f1 100644
|
|
||||||
--- a/cmake/sdlchecks.cmake
|
|
||||||
+++ b/cmake/sdlchecks.cmake
|
|
||||||
@@ -352,7 +352,7 @@ endmacro()
|
|
||||||
# - HAVE_SDL_LOADSO opt
|
|
||||||
macro(CheckLibSampleRate)
|
|
||||||
if(SDL_LIBSAMPLERATE)
|
|
||||||
- find_package(SampleRate QUIET)
|
|
||||||
+ find_package(SampleRate CONFIG REQUIRED)
|
|
||||||
if(SampleRate_FOUND AND TARGET SampleRate::samplerate)
|
|
||||||
set(HAVE_LIBSAMPLERATE TRUE)
|
|
||||||
set(HAVE_LIBSAMPLERATE_H TRUE)
|
|
137
dependencies/vcpkg_overlay_ports/sdl2/portfile.cmake
vendored
137
dependencies/vcpkg_overlay_ports/sdl2/portfile.cmake
vendored
@ -1,137 +0,0 @@
|
|||||||
vcpkg_from_github(
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libsdl-org/SDL
|
|
||||||
REF "release-${VERSION}"
|
|
||||||
SHA512 c7635a83a52f3970a372b804a8631f0a7e6b8d89aed1117bcc54a2040ad0928122175004cf2b42cf84a4fd0f86236f779229eaa63dfa6ca9c89517f999c5ff1c
|
|
||||||
HEAD_REF main
|
|
||||||
PATCHES
|
|
||||||
deps.patch
|
|
||||||
alsa-dep-fix.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SDL_SHARED)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" FORCE_STATIC_VCRT)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
alsa SDL_ALSA
|
|
||||||
alsa CMAKE_REQUIRE_FIND_PACKAGE_ALSA
|
|
||||||
ibus SDL_IBUS
|
|
||||||
samplerate SDL_LIBSAMPLERATE
|
|
||||||
vulkan SDL_VULKAN
|
|
||||||
wayland SDL_WAYLAND
|
|
||||||
x11 SDL_X11
|
|
||||||
INVERTED_FEATURES
|
|
||||||
alsa CMAKE_DISABLE_FIND_PACKAGE_ALSA
|
|
||||||
)
|
|
||||||
|
|
||||||
if ("x11" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Xorg dependencies to use feature x11:\nsudo apt install libx11-dev libxft-dev libxext-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("wayland" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Wayland dependencies to use feature wayland:\nsudo apt install libwayland-dev libxkbcommon-dev libegl1-mesa-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("ibus" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install ibus dependencies to use feature ibus:\nsudo apt install libibus-1.0-dev\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
set(configure_opts WINDOWS_USE_MSBUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
${configure_opts}
|
|
||||||
OPTIONS ${FEATURE_OPTIONS}
|
|
||||||
-DSDL_STATIC=${SDL_STATIC}
|
|
||||||
-DSDL_SHARED=${SDL_SHARED}
|
|
||||||
-DSDL_FORCE_STATIC_VCRT=${FORCE_STATIC_VCRT}
|
|
||||||
-DSDL_LIBC=ON
|
|
||||||
-DSDL_TEST=OFF
|
|
||||||
-DSDL_INSTALL_CMAKEDIR="cmake"
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON
|
|
||||||
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON
|
|
||||||
-DSDL_LIBSAMPLERATE_SHARED=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
SDL_FORCE_STATIC_VCRT
|
|
||||||
PKG_CONFIG_USE_CMAKE_PREFIX_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/licenses"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/aclocal"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB BINS "${CURRENT_PACKAGES_DIR}/debug/bin/*" "${CURRENT_PACKAGES_DIR}/bin/*")
|
|
||||||
if(NOT BINS)
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_UWP AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/lib/SDL2main.lib" "${CURRENT_PACKAGES_DIR}/lib/manual-link/SDL2main.lib")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/SDL2maind.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link/SDL2maind.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB SHARE_FILES "${CURRENT_PACKAGES_DIR}/share/sdl2/*.cmake")
|
|
||||||
foreach(SHARE_FILE ${SHARE_FILES})
|
|
||||||
vcpkg_replace_string("${SHARE_FILE}" "lib/SDL2main" "lib/manual-link/SDL2main")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
|
|
||||||
set(DYLIB_COMPATIBILITY_VERSION_REGEX "set\\(DYLIB_COMPATIBILITY_VERSION (.+)\\)")
|
|
||||||
set(DYLIB_CURRENT_VERSION_REGEX "set\\(DYLIB_CURRENT_VERSION (.+)\\)")
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_COMPATIBILITY_VERSION REGEX ${DYLIB_COMPATIBILITY_VERSION_REGEX})
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_CURRENT_VERSION REGEX ${DYLIB_CURRENT_VERSION_REGEX})
|
|
||||||
string(REGEX REPLACE ${DYLIB_COMPATIBILITY_VERSION_REGEX} "\\1" DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPATIBILITY_VERSION}")
|
|
||||||
string(REGEX REPLACE ${DYLIB_CURRENT_VERSION_REGEX} "\\1" DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}")
|
|
||||||
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2main" "-lSDL2maind")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2 " "-lSDL2d ")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-static " "-lSDL2-staticd ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-lSDL2-static " " ")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-staticd " " ")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "d")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt")
|
|
8
dependencies/vcpkg_overlay_ports/sdl2/usage
vendored
8
dependencies/vcpkg_overlay_ports/sdl2/usage
vendored
@ -1,8 +0,0 @@
|
|||||||
sdl2 provides CMake targets:
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
|
||||||
target_link_libraries(main
|
|
||||||
PRIVATE
|
|
||||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
|
||||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
|
||||||
)
|
|
68
dependencies/vcpkg_overlay_ports/sdl2/vcpkg.json
vendored
68
dependencies/vcpkg_overlay_ports/sdl2/vcpkg.json
vendored
@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"version": "2.30.0",
|
|
||||||
"description": "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.",
|
|
||||||
"homepage": "https://www.libsdl.org/download-2.0.php",
|
|
||||||
"license": "Zlib",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "dbus",
|
|
||||||
"default-features": false,
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
{
|
|
||||||
"name": "ibus",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "wayland",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "x11",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"alsa": {
|
|
||||||
"description": "Support for alsa audio",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "alsa",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ibus": {
|
|
||||||
"description": "Build with ibus IME support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"samplerate": {
|
|
||||||
"description": "Use libsamplerate for audio rate conversion",
|
|
||||||
"dependencies": [
|
|
||||||
"libsamplerate"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"vulkan": {
|
|
||||||
"description": "Vulkan functionality for SDL"
|
|
||||||
},
|
|
||||||
"wayland": {
|
|
||||||
"description": "Build with Wayland support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 support",
|
|
||||||
"supports": "!windows"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/FindCMath.cmake b/cmake/FindCMath.cmake
|
|
||||||
index ad92218..dd42aba 100644
|
|
||||||
--- a/cmake/FindCMath.cmake
|
|
||||||
+++ b/cmake/FindCMath.cmake
|
|
||||||
@@ -31,7 +31,7 @@ include(CheckSymbolExists)
|
|
||||||
include(CheckLibraryExists)
|
|
||||||
|
|
||||||
check_symbol_exists(pow "math.h" CMath_HAVE_LIBC_POW)
|
|
||||||
-find_library(CMath_LIBRARY NAMES m)
|
|
||||||
+find_library(CMath_LIBRARY NAMES m PATHS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
|
||||||
|
|
||||||
if(NOT CMath_HAVE_LIBC_POW)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
|
|
@ -1,86 +0,0 @@
|
|||||||
vcpkg_from_gitlab(
|
|
||||||
GITLAB_URL https://gitlab.com
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libtiff/libtiff
|
|
||||||
REF "v${VERSION}"
|
|
||||||
SHA512 ef2f1d424219d9e245069b7d23e78f5e817cf6ee516d46694915ab6c8909522166f84997513d20a702f4e52c3f18467813935b328fafa34bea5156dee00f66fa
|
|
||||||
HEAD_REF master
|
|
||||||
PATCHES
|
|
||||||
FindCMath.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
cxx cxx
|
|
||||||
jpeg jpeg
|
|
||||||
jpeg CMAKE_REQUIRE_FIND_PACKAGE_JPEG
|
|
||||||
libdeflate libdeflate
|
|
||||||
libdeflate CMAKE_REQUIRE_FIND_PACKAGE_Deflate
|
|
||||||
lzma lzma
|
|
||||||
lzma CMAKE_REQUIRE_FIND_PACKAGE_liblzma
|
|
||||||
tools tiff-tools
|
|
||||||
webp webp
|
|
||||||
webp CMAKE_REQUIRE_FIND_PACKAGE_WebP
|
|
||||||
zip zlib
|
|
||||||
zip CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
|
|
||||||
zstd zstd
|
|
||||||
zstd CMAKE_REQUIRE_FIND_PACKAGE_ZSTD
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
OPTIONS
|
|
||||||
${FEATURE_OPTIONS}
|
|
||||||
-DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON
|
|
||||||
-Dtiff-docs=OFF
|
|
||||||
-Dtiff-contrib=OFF
|
|
||||||
-Dtiff-tests=OFF
|
|
||||||
-Djbig=OFF # This is disabled by default due to GPL/Proprietary licensing.
|
|
||||||
-Djpeg12=OFF
|
|
||||||
-Dlerc=OFF
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_OpenGL=ON
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_GLUT=ON
|
|
||||||
-DZSTD_HAVE_DECOMPRESS_STREAM=ON
|
|
||||||
-DHAVE_JPEGTURBO_DUAL_MODE_8_12=OFF
|
|
||||||
OPTIONS_DEBUG
|
|
||||||
-DCMAKE_DEBUG_POSTFIX=d # tiff sets "d" for MSVC only.
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_GLUT
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_OpenGL
|
|
||||||
ZSTD_HAVE_DECOMPRESS_STREAM
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
|
|
||||||
# CMake config wasn't packaged in the past and is not yet usable now,
|
|
||||||
# cf. https://gitlab.com/libtiff/libtiff/-/merge_requests/496
|
|
||||||
# vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/tiff")
|
|
||||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/lib/cmake" "${CURRENT_PACKAGES_DIR}/debug/lib/cmake")
|
|
||||||
|
|
||||||
set(_file "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/libtiff-4.pc")
|
|
||||||
if(EXISTS "${_file}")
|
|
||||||
vcpkg_replace_string("${_file}" "-ltiff" "-ltiffd")
|
|
||||||
endif()
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY)
|
|
||||||
|
|
||||||
if ("tools" IN_LIST FEATURES)
|
|
||||||
vcpkg_copy_tools(TOOL_NAMES
|
|
||||||
tiffcp
|
|
||||||
tiffdump
|
|
||||||
tiffinfo
|
|
||||||
tiffset
|
|
||||||
tiffsplit
|
|
||||||
AUTO_CLEAN
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
file(COPY "${CURRENT_PORT_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.md")
|
|
9
dependencies/vcpkg_overlay_ports/tiff/usage
vendored
9
dependencies/vcpkg_overlay_ports/tiff/usage
vendored
@ -1,9 +0,0 @@
|
|||||||
tiff is compatible with built-in CMake targets:
|
|
||||||
|
|
||||||
find_package(TIFF REQUIRED)
|
|
||||||
target_link_libraries(main PRIVATE TIFF::TIFF)
|
|
||||||
|
|
||||||
tiff provides pkg-config modules:
|
|
||||||
|
|
||||||
# Tag Image File Format (TIFF) library.
|
|
||||||
libtiff-4
|
|
@ -1,104 +0,0 @@
|
|||||||
cmake_policy(PUSH)
|
|
||||||
cmake_policy(SET CMP0012 NEW)
|
|
||||||
cmake_policy(SET CMP0057 NEW)
|
|
||||||
set(z_vcpkg_tiff_find_options "")
|
|
||||||
if("REQUIRED" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "REQUIRED")
|
|
||||||
endif()
|
|
||||||
if("QUIET" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "QUIET")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
_find_package(${ARGS})
|
|
||||||
|
|
||||||
if(TIFF_FOUND AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static")
|
|
||||||
include(SelectLibraryConfigurations)
|
|
||||||
set(z_vcpkg_tiff_link_libraries "")
|
|
||||||
set(z_vcpkg_tiff_libraries "")
|
|
||||||
if("@webp@")
|
|
||||||
find_package(WebP CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:WebP::WebP>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${WebP_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@lzma@")
|
|
||||||
find_package(LibLZMA ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:LibLZMA::LibLZMA>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${LIBLZMA_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@jpeg@")
|
|
||||||
find_package(JPEG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:JPEG::JPEG>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${JPEG_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@zstd@")
|
|
||||||
find_package(zstd CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET zstd::libzstd_shared)
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_shared>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_static>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_tiff_zstd_configs "${z_vcpkg_tiff_zstd_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_tiff_zstd_configs)
|
|
||||||
get_target_property(ZSTD_LIBRARY_${z_vcpkg_config} "${z_vcpkg_tiff_zstd_target}" "${z_vcpkg_tiff_zstd_target_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(ZSTD)
|
|
||||||
if(NOT TARGET ZSTD::ZSTD)
|
|
||||||
add_library(ZSTD::ZSTD INTERFACE IMPORTED)
|
|
||||||
set_property(TARGET ZSTD::ZSTD APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_zstd})
|
|
||||||
endif()
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries ${z_vcpkg_tiff_zstd})
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZSTD_LIBRARIES})
|
|
||||||
unset(z_vcpkg_tiff_zstd)
|
|
||||||
unset(z_vcpkg_tiff_zstd_configs)
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_tiff_zstd_target)
|
|
||||||
endif()
|
|
||||||
if("@libdeflate@")
|
|
||||||
find_package(libdeflate ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET libdeflate::libdeflate_shared)
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_libdeflate_configs "${z_vcpkg_libdeflate_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_libdeflate_configs)
|
|
||||||
get_target_property(Z_VCPKG_DEFLATE_LIBRARY_${z_vcpkg_config} "${z_vcpkg_libdeflate_target}" "${z_vcpkg_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(Z_VCPKG_DEFLATE)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:${z_vcpkg_libdeflate_target}>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${Z_VCPKG_DEFLATE_LIBRARIES})
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_libdeflate_configs)
|
|
||||||
unset(z_vcpkg_libdeflate_target)
|
|
||||||
unset(z_vcpkg_property)
|
|
||||||
unset(Z_VCPKG_DEFLATE_FOUND)
|
|
||||||
endif()
|
|
||||||
if("@zlib@")
|
|
||||||
find_package(ZLIB ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:ZLIB::ZLIB>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZLIB_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(UNIX)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries m)
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(TARGET TIFF::TIFF)
|
|
||||||
set_property(TARGET TIFF::TIFF APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_link_libraries})
|
|
||||||
endif()
|
|
||||||
list(APPEND TIFF_LIBRARIES ${z_vcpkg_tiff_libraries})
|
|
||||||
unset(z_vcpkg_tiff_link_libraries)
|
|
||||||
unset(z_vcpkg_tiff_libraries)
|
|
||||||
endif()
|
|
||||||
unset(z_vcpkg_tiff_find_options)
|
|
||||||
cmake_policy(POP)
|
|
67
dependencies/vcpkg_overlay_ports/tiff/vcpkg.json
vendored
67
dependencies/vcpkg_overlay_ports/tiff/vcpkg.json
vendored
@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"version": "4.6.0",
|
|
||||||
"port-version": 2,
|
|
||||||
"description": "A library that supports the manipulation of TIFF image files",
|
|
||||||
"homepage": "https://libtiff.gitlab.io/libtiff/",
|
|
||||||
"license": "libtiff",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
"jpeg",
|
|
||||||
"zip"
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"cxx": {
|
|
||||||
"description": "Build C++ libtiffxx library"
|
|
||||||
},
|
|
||||||
"jpeg": {
|
|
||||||
"description": "Support JPEG compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libjpeg-turbo"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"libdeflate": {
|
|
||||||
"description": "Use libdeflate for faster ZIP support",
|
|
||||||
"dependencies": [
|
|
||||||
"libdeflate",
|
|
||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"default-features": false,
|
|
||||||
"features": [
|
|
||||||
"zip"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"description": "Build tools"
|
|
||||||
},
|
|
||||||
"webp": {
|
|
||||||
"description": "Support WEBP compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libwebp"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zip": {
|
|
||||||
"description": "Support ZIP/deflate compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zlib"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zstd": {
|
|
||||||
"description": "Support ZSTD compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zstd"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
|
|
||||||
index 8cde1ffe0..d4d09f223 100644
|
|
||||||
--- a/tools/CMakeLists.txt
|
|
||||||
+++ b/tools/CMakeLists.txt
|
|
||||||
@@ -91,7 +91,9 @@ endif()
|
|
||||||
add_executable(dbus-launch ${dbus_launch_SOURCES})
|
|
||||||
target_link_libraries(dbus-launch ${DBUS_LIBRARIES})
|
|
||||||
if(DBUS_BUILD_X11)
|
|
||||||
- target_link_libraries(dbus-launch ${X11_LIBRARIES} )
|
|
||||||
+ find_package(Threads REQUIRED)
|
|
||||||
+ target_link_libraries(dbus-launch ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_Xau_LIB} ${X11_Xdmcp_LIB} Threads::Threads)
|
|
||||||
+ target_include_directories(dbus-launch PRIVATE ${X11_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
install(TARGETS dbus-launch ${INSTALL_TARGETS_DEFAULT_ARGS})
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
|||||||
diff --git a/cmake/ConfigureChecks.cmake b/cmake/ConfigureChecks.cmake
|
|
||||||
index b7f3702..e2336ba 100644
|
|
||||||
--- a/cmake/ConfigureChecks.cmake
|
|
||||||
+++ b/cmake/ConfigureChecks.cmake
|
|
||||||
@@ -51,6 +51,7 @@ check_symbol_exists(closefrom "unistd.h" HAVE_CLOSEFROM) #
|
|
||||||
check_symbol_exists(environ "unistd.h" HAVE_DECL_ENVIRON)
|
|
||||||
check_symbol_exists(fstatfs "sys/vfs.h" HAVE_FSTATFS)
|
|
||||||
check_symbol_exists(getgrouplist "grp.h" HAVE_GETGROUPLIST) # dbus-sysdeps.c
|
|
||||||
+check_symbol_exists(getpeereid "sys/types.h;unistd.h" HAVE_GETPEEREID) # dbus-sysdeps.c,
|
|
||||||
check_symbol_exists(getpeerucred "ucred.h" HAVE_GETPEERUCRED) # dbus-sysdeps.c, dbus-sysdeps-win.c
|
|
||||||
check_symbol_exists(getpwnam_r "errno.h;pwd.h" HAVE_GETPWNAM_R) # dbus-sysdeps-util-unix.c
|
|
||||||
check_symbol_exists(getrandom "sys/random.h" HAVE_GETRANDOM)
|
|
||||||
diff --git a/cmake/config.h.cmake b/cmake/config.h.cmake
|
|
||||||
index 77fc19c..2f25643 100644
|
|
||||||
--- a/cmake/config.h.cmake
|
|
||||||
+++ b/cmake/config.h.cmake
|
|
||||||
@@ -140,6 +140,9 @@
|
|
||||||
/* Define to 1 if you have getgrouplist */
|
|
||||||
#cmakedefine HAVE_GETGROUPLIST 1
|
|
||||||
|
|
||||||
+/* Define to 1 if you have getpeereid */
|
|
||||||
+#cmakedefine HAVE_GETPEEREID 1
|
|
||||||
+
|
|
||||||
/* Define to 1 if you have getpeerucred */
|
|
||||||
#cmakedefine HAVE_GETPEERUCRED 1
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
|||||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
||||||
index d3ec71b..932066a 100644
|
|
||||||
--- a/CMakeLists.txt
|
|
||||||
+++ b/CMakeLists.txt
|
|
||||||
@@ -141,6 +141,10 @@ if(DBUS_LINUX)
|
|
||||||
if(ENABLE_SYSTEMD AND SYSTEMD_FOUND)
|
|
||||||
set(DBUS_BUS_ENABLE_SYSTEMD ON)
|
|
||||||
set(HAVE_SYSTEMD ${SYSTEMD_FOUND})
|
|
||||||
+ pkg_check_modules(SYSTEMD libsystemd IMPORTED_TARGET)
|
|
||||||
+ set(SYSTEMD_LIBRARIES PkgConfig::SYSTEMD CACHE INTERNAL "")
|
|
||||||
+ else()
|
|
||||||
+ set(SYSTEMD_LIBRARIES "" CACHE INTERNAL "")
|
|
||||||
endif()
|
|
||||||
option(ENABLE_USER_SESSION "enable user-session semantics for session bus under systemd" OFF)
|
|
||||||
set(DBUS_ENABLE_USER_SESSION ${ENABLE_USER_SESSION})
|
|
@ -1,21 +0,0 @@
|
|||||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
|
||||||
index caef738..b878f42 100644
|
|
||||||
--- a/CMakeLists.txt
|
|
||||||
+++ b/CMakeLists.txt
|
|
||||||
@@ -724,11 +724,11 @@ add_custom_target(help-options
|
|
||||||
#
|
|
||||||
if(DBUS_ENABLE_PKGCONFIG)
|
|
||||||
set(PLATFORM_LIBS pthread ${LIBRT})
|
|
||||||
- if(PKG_CONFIG_FOUND)
|
|
||||||
- # convert lists of link libraries into -lstdc++ -lm etc..
|
|
||||||
- foreach(LIB ${CMAKE_C_IMPLICIT_LINK_LIBRARIES} ${PLATFORM_LIBS})
|
|
||||||
- set(LIBDBUS_LIBS "${LIBDBUS_LIBS} -l${LIB}")
|
|
||||||
- endforeach()
|
|
||||||
+ if(1)
|
|
||||||
+ set(LIBDBUS_LIBS "${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
+ if(LIBRT)
|
|
||||||
+ string(APPEND LIBDBUS_LIBS " -lrt")
|
|
||||||
+ endif()
|
|
||||||
set(original_prefix "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
if(DBUS_RELOCATABLE)
|
|
||||||
set(pkgconfig_prefix "\${pcfiledir}/../..")
|
|
@ -1,88 +0,0 @@
|
|||||||
vcpkg_check_linkage(ONLY_DYNAMIC_LIBRARY)
|
|
||||||
|
|
||||||
vcpkg_from_gitlab(
|
|
||||||
GITLAB_URL https://gitlab.freedesktop.org/
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO dbus/dbus
|
|
||||||
REF "dbus-${VERSION}"
|
|
||||||
SHA512 8e476b408514e6540c36beb84e8025827c22cda8958b6eb74d22b99c64765eb3cd5a6502aea546e3e5f0534039857b37edee89c659acef40e7cab0939947d4af
|
|
||||||
HEAD_REF master
|
|
||||||
PATCHES
|
|
||||||
cmake.dep.patch
|
|
||||||
pkgconfig.patch
|
|
||||||
getpeereid.patch # missing check from configure.ac
|
|
||||||
libsystemd.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS options
|
|
||||||
FEATURES
|
|
||||||
systemd ENABLE_SYSTEMD
|
|
||||||
x11 DBUS_BUILD_X11
|
|
||||||
x11 CMAKE_REQUIRE_FIND_PACKAGE_X11
|
|
||||||
)
|
|
||||||
|
|
||||||
unset(ENV{DBUSDIR})
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
OPTIONS
|
|
||||||
-DDBUS_BUILD_TESTS=OFF
|
|
||||||
-DDBUS_ENABLE_DOXYGEN_DOCS=OFF
|
|
||||||
-DDBUS_ENABLE_XML_DOCS=OFF
|
|
||||||
-DDBUS_INSTALL_SYSTEM_LIBS=OFF
|
|
||||||
#-DDBUS_SERVICE=ON
|
|
||||||
-DDBUS_WITH_GLIB=OFF
|
|
||||||
-DTHREADS_PREFER_PTHREAD_FLAG=ON
|
|
||||||
-DXSLTPROC_EXECUTABLE=FALSE
|
|
||||||
"-DCMAKE_INSTALL_SYSCONFDIR=${CURRENT_PACKAGES_DIR}/etc/${PORT}"
|
|
||||||
"-DWITH_SYSTEMD_SYSTEMUNITDIR=lib/systemd/system"
|
|
||||||
"-DWITH_SYSTEMD_USERUNITDIR=lib/systemd/user"
|
|
||||||
${options}
|
|
||||||
OPTIONS_RELEASE
|
|
||||||
-DDBUS_DISABLE_ASSERT=OFF
|
|
||||||
-DDBUS_ENABLE_STATS=OFF
|
|
||||||
-DDBUS_ENABLE_VERBOSE_MODE=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
DBUS_BUILD_X11
|
|
||||||
DBUS_WITH_GLIB
|
|
||||||
ENABLE_SYSTEMD
|
|
||||||
THREADS_PREFER_PTHREAD_FLAG
|
|
||||||
WITH_SYSTEMD_SYSTEMUNITDIR
|
|
||||||
WITH_SYSTEMD_USERUNITDIR
|
|
||||||
)
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
vcpkg_cmake_config_fixup(PACKAGE_NAME "DBus1" CONFIG_PATH "lib/cmake/DBus1")
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/var/"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/etc"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/services"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/session.d"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/system-services"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/system.d"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/system.conf"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/dbus-1/system.conf"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/doc"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/var"
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/dbus-1/session.conf" "<include ignore_missing=\"yes\">${CURRENT_PACKAGES_DIR}/etc/dbus/dbus-1/session.conf</include>" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/dbus-1/session.conf" "<includedir>${CURRENT_PACKAGES_DIR}/etc/dbus/dbus-1/session.d</includedir>" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/share/dbus-1/session.conf" "<include ignore_missing=\"yes\">${CURRENT_PACKAGES_DIR}/etc/dbus/dbus-1/session-local.conf</include>" "")
|
|
||||||
|
|
||||||
set(TOOLS daemon launch monitor run-session send test-tool update-activation-environment)
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS)
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/tools/${PORT}")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/bin/dbus-env.bat" "${CURRENT_PACKAGES_DIR}/tools/${PORT}/dbus-env.bat")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/tools/${PORT}/dbus-env.bat" "${CURRENT_PACKAGES_DIR}" "%~dp0/../..")
|
|
||||||
else()
|
|
||||||
list(APPEND TOOLS cleanup-sockets uuidgen)
|
|
||||||
endif()
|
|
||||||
list(TRANSFORM TOOLS PREPEND "dbus-" )
|
|
||||||
vcpkg_copy_tools(TOOL_NAMES ${TOOLS} AUTO_CLEAN)
|
|
||||||
|
|
||||||
file(INSTALL "${SOURCE_PATH}/COPYING" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}" RENAME copyright)
|
|
@ -1,30 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dbus",
|
|
||||||
"version": "1.15.8",
|
|
||||||
"port-version": 2,
|
|
||||||
"description": "D-Bus specification and reference implementation, including libdbus and dbus-daemon",
|
|
||||||
"homepage": "https://gitlab.freedesktop.org/dbus/dbus",
|
|
||||||
"license": "AFL-2.1 OR GPL-2.0-or-later",
|
|
||||||
"supports": "!uwp & !staticcrt",
|
|
||||||
"dependencies": [
|
|
||||||
"expat",
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 autolaunch support",
|
|
||||||
"dependencies": [
|
|
||||||
"libx11"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/SDL2Config.cmake.in b/SDL2Config.cmake.in
|
|
||||||
index cc8bcf26d..ead829767 100644
|
|
||||||
--- a/SDL2Config.cmake.in
|
|
||||||
+++ b/SDL2Config.cmake.in
|
|
||||||
@@ -35,7 +35,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/sdlfind.cmake")
|
|
||||||
|
|
||||||
set(SDL_ALSA @SDL_ALSA@)
|
|
||||||
set(SDL_ALSA_SHARED @SDL_ALSA_SHARED@)
|
|
||||||
-if(SDL_ALSA AND NOT SDL_ALSA_SHARED AND TARGET SDL2::SDL2-static)
|
|
||||||
+if(SDL_ALSA)
|
|
||||||
sdlFindALSA()
|
|
||||||
endif()
|
|
||||||
unset(SDL_ALSA)
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
|
|
||||||
index 65a98efbe..2f99f28f1 100644
|
|
||||||
--- a/cmake/sdlchecks.cmake
|
|
||||||
+++ b/cmake/sdlchecks.cmake
|
|
||||||
@@ -352,7 +352,7 @@ endmacro()
|
|
||||||
# - HAVE_SDL_LOADSO opt
|
|
||||||
macro(CheckLibSampleRate)
|
|
||||||
if(SDL_LIBSAMPLERATE)
|
|
||||||
- find_package(SampleRate QUIET)
|
|
||||||
+ find_package(SampleRate CONFIG REQUIRED)
|
|
||||||
if(SampleRate_FOUND AND TARGET SampleRate::samplerate)
|
|
||||||
set(HAVE_LIBSAMPLERATE TRUE)
|
|
||||||
set(HAVE_LIBSAMPLERATE_H TRUE)
|
|
@ -1,137 +0,0 @@
|
|||||||
vcpkg_from_github(
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libsdl-org/SDL
|
|
||||||
REF "release-${VERSION}"
|
|
||||||
SHA512 c7635a83a52f3970a372b804a8631f0a7e6b8d89aed1117bcc54a2040ad0928122175004cf2b42cf84a4fd0f86236f779229eaa63dfa6ca9c89517f999c5ff1c
|
|
||||||
HEAD_REF main
|
|
||||||
PATCHES
|
|
||||||
deps.patch
|
|
||||||
alsa-dep-fix.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SDL_SHARED)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" FORCE_STATIC_VCRT)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
alsa SDL_ALSA
|
|
||||||
alsa CMAKE_REQUIRE_FIND_PACKAGE_ALSA
|
|
||||||
ibus SDL_IBUS
|
|
||||||
samplerate SDL_LIBSAMPLERATE
|
|
||||||
vulkan SDL_VULKAN
|
|
||||||
wayland SDL_WAYLAND
|
|
||||||
x11 SDL_X11
|
|
||||||
INVERTED_FEATURES
|
|
||||||
alsa CMAKE_DISABLE_FIND_PACKAGE_ALSA
|
|
||||||
)
|
|
||||||
|
|
||||||
if ("x11" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Xorg dependencies to use feature x11:\nsudo apt install libx11-dev libxft-dev libxext-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("wayland" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Wayland dependencies to use feature wayland:\nsudo apt install libwayland-dev libxkbcommon-dev libegl1-mesa-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("ibus" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install ibus dependencies to use feature ibus:\nsudo apt install libibus-1.0-dev\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
set(configure_opts WINDOWS_USE_MSBUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
${configure_opts}
|
|
||||||
OPTIONS ${FEATURE_OPTIONS}
|
|
||||||
-DSDL_STATIC=${SDL_STATIC}
|
|
||||||
-DSDL_SHARED=${SDL_SHARED}
|
|
||||||
-DSDL_FORCE_STATIC_VCRT=${FORCE_STATIC_VCRT}
|
|
||||||
-DSDL_LIBC=ON
|
|
||||||
-DSDL_TEST=OFF
|
|
||||||
-DSDL_INSTALL_CMAKEDIR="cmake"
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON
|
|
||||||
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON
|
|
||||||
-DSDL_LIBSAMPLERATE_SHARED=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
SDL_FORCE_STATIC_VCRT
|
|
||||||
PKG_CONFIG_USE_CMAKE_PREFIX_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/licenses"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/aclocal"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB BINS "${CURRENT_PACKAGES_DIR}/debug/bin/*" "${CURRENT_PACKAGES_DIR}/bin/*")
|
|
||||||
if(NOT BINS)
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_UWP AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/lib/SDL2main.lib" "${CURRENT_PACKAGES_DIR}/lib/manual-link/SDL2main.lib")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/SDL2maind.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link/SDL2maind.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB SHARE_FILES "${CURRENT_PACKAGES_DIR}/share/sdl2/*.cmake")
|
|
||||||
foreach(SHARE_FILE ${SHARE_FILES})
|
|
||||||
vcpkg_replace_string("${SHARE_FILE}" "lib/SDL2main" "lib/manual-link/SDL2main")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
|
|
||||||
set(DYLIB_COMPATIBILITY_VERSION_REGEX "set\\(DYLIB_COMPATIBILITY_VERSION (.+)\\)")
|
|
||||||
set(DYLIB_CURRENT_VERSION_REGEX "set\\(DYLIB_CURRENT_VERSION (.+)\\)")
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_COMPATIBILITY_VERSION REGEX ${DYLIB_COMPATIBILITY_VERSION_REGEX})
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_CURRENT_VERSION REGEX ${DYLIB_CURRENT_VERSION_REGEX})
|
|
||||||
string(REGEX REPLACE ${DYLIB_COMPATIBILITY_VERSION_REGEX} "\\1" DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPATIBILITY_VERSION}")
|
|
||||||
string(REGEX REPLACE ${DYLIB_CURRENT_VERSION_REGEX} "\\1" DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}")
|
|
||||||
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2main" "-lSDL2maind")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2 " "-lSDL2d ")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-static " "-lSDL2-staticd ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-lSDL2-static " " ")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-staticd " " ")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "d")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt")
|
|
@ -1,8 +0,0 @@
|
|||||||
sdl2 provides CMake targets:
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
|
||||||
target_link_libraries(main
|
|
||||||
PRIVATE
|
|
||||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
|
||||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
|
||||||
)
|
|
@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"version": "2.30.0",
|
|
||||||
"description": "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.",
|
|
||||||
"homepage": "https://www.libsdl.org/download-2.0.php",
|
|
||||||
"license": "Zlib",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "dbus",
|
|
||||||
"default-features": false,
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
{
|
|
||||||
"name": "ibus",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "wayland",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "x11",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"alsa": {
|
|
||||||
"description": "Support for alsa audio",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "alsa",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ibus": {
|
|
||||||
"description": "Build with ibus IME support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"samplerate": {
|
|
||||||
"description": "Use libsamplerate for audio rate conversion",
|
|
||||||
"dependencies": [
|
|
||||||
"libsamplerate"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"vulkan": {
|
|
||||||
"description": "Vulkan functionality for SDL"
|
|
||||||
},
|
|
||||||
"wayland": {
|
|
||||||
"description": "Build with Wayland support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 support",
|
|
||||||
"supports": "!windows"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/FindCMath.cmake b/cmake/FindCMath.cmake
|
|
||||||
index ad92218..dd42aba 100644
|
|
||||||
--- a/cmake/FindCMath.cmake
|
|
||||||
+++ b/cmake/FindCMath.cmake
|
|
||||||
@@ -31,7 +31,7 @@ include(CheckSymbolExists)
|
|
||||||
include(CheckLibraryExists)
|
|
||||||
|
|
||||||
check_symbol_exists(pow "math.h" CMath_HAVE_LIBC_POW)
|
|
||||||
-find_library(CMath_LIBRARY NAMES m)
|
|
||||||
+find_library(CMath_LIBRARY NAMES m PATHS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
|
||||||
|
|
||||||
if(NOT CMath_HAVE_LIBC_POW)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
|
|
@ -1,86 +0,0 @@
|
|||||||
vcpkg_from_gitlab(
|
|
||||||
GITLAB_URL https://gitlab.com
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libtiff/libtiff
|
|
||||||
REF "v${VERSION}"
|
|
||||||
SHA512 ef2f1d424219d9e245069b7d23e78f5e817cf6ee516d46694915ab6c8909522166f84997513d20a702f4e52c3f18467813935b328fafa34bea5156dee00f66fa
|
|
||||||
HEAD_REF master
|
|
||||||
PATCHES
|
|
||||||
FindCMath.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
cxx cxx
|
|
||||||
jpeg jpeg
|
|
||||||
jpeg CMAKE_REQUIRE_FIND_PACKAGE_JPEG
|
|
||||||
libdeflate libdeflate
|
|
||||||
libdeflate CMAKE_REQUIRE_FIND_PACKAGE_Deflate
|
|
||||||
lzma lzma
|
|
||||||
lzma CMAKE_REQUIRE_FIND_PACKAGE_liblzma
|
|
||||||
tools tiff-tools
|
|
||||||
webp webp
|
|
||||||
webp CMAKE_REQUIRE_FIND_PACKAGE_WebP
|
|
||||||
zip zlib
|
|
||||||
zip CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
|
|
||||||
zstd zstd
|
|
||||||
zstd CMAKE_REQUIRE_FIND_PACKAGE_ZSTD
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
OPTIONS
|
|
||||||
${FEATURE_OPTIONS}
|
|
||||||
-DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON
|
|
||||||
-Dtiff-docs=OFF
|
|
||||||
-Dtiff-contrib=OFF
|
|
||||||
-Dtiff-tests=OFF
|
|
||||||
-Djbig=OFF # This is disabled by default due to GPL/Proprietary licensing.
|
|
||||||
-Djpeg12=OFF
|
|
||||||
-Dlerc=OFF
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_OpenGL=ON
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_GLUT=ON
|
|
||||||
-DZSTD_HAVE_DECOMPRESS_STREAM=ON
|
|
||||||
-DHAVE_JPEGTURBO_DUAL_MODE_8_12=OFF
|
|
||||||
OPTIONS_DEBUG
|
|
||||||
-DCMAKE_DEBUG_POSTFIX=d # tiff sets "d" for MSVC only.
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_GLUT
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_OpenGL
|
|
||||||
ZSTD_HAVE_DECOMPRESS_STREAM
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
|
|
||||||
# CMake config wasn't packaged in the past and is not yet usable now,
|
|
||||||
# cf. https://gitlab.com/libtiff/libtiff/-/merge_requests/496
|
|
||||||
# vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/tiff")
|
|
||||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/lib/cmake" "${CURRENT_PACKAGES_DIR}/debug/lib/cmake")
|
|
||||||
|
|
||||||
set(_file "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/libtiff-4.pc")
|
|
||||||
if(EXISTS "${_file}")
|
|
||||||
vcpkg_replace_string("${_file}" "-ltiff" "-ltiffd")
|
|
||||||
endif()
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY)
|
|
||||||
|
|
||||||
if ("tools" IN_LIST FEATURES)
|
|
||||||
vcpkg_copy_tools(TOOL_NAMES
|
|
||||||
tiffcp
|
|
||||||
tiffdump
|
|
||||||
tiffinfo
|
|
||||||
tiffset
|
|
||||||
tiffsplit
|
|
||||||
AUTO_CLEAN
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
file(COPY "${CURRENT_PORT_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.md")
|
|
@ -1,9 +0,0 @@
|
|||||||
tiff is compatible with built-in CMake targets:
|
|
||||||
|
|
||||||
find_package(TIFF REQUIRED)
|
|
||||||
target_link_libraries(main PRIVATE TIFF::TIFF)
|
|
||||||
|
|
||||||
tiff provides pkg-config modules:
|
|
||||||
|
|
||||||
# Tag Image File Format (TIFF) library.
|
|
||||||
libtiff-4
|
|
@ -1,104 +0,0 @@
|
|||||||
cmake_policy(PUSH)
|
|
||||||
cmake_policy(SET CMP0012 NEW)
|
|
||||||
cmake_policy(SET CMP0057 NEW)
|
|
||||||
set(z_vcpkg_tiff_find_options "")
|
|
||||||
if("REQUIRED" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "REQUIRED")
|
|
||||||
endif()
|
|
||||||
if("QUIET" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "QUIET")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
_find_package(${ARGS})
|
|
||||||
|
|
||||||
if(TIFF_FOUND AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static")
|
|
||||||
include(SelectLibraryConfigurations)
|
|
||||||
set(z_vcpkg_tiff_link_libraries "")
|
|
||||||
set(z_vcpkg_tiff_libraries "")
|
|
||||||
if("@webp@")
|
|
||||||
find_package(WebP CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:WebP::WebP>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${WebP_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@lzma@")
|
|
||||||
find_package(LibLZMA ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:LibLZMA::LibLZMA>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${LIBLZMA_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@jpeg@")
|
|
||||||
find_package(JPEG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:JPEG::JPEG>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${JPEG_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@zstd@")
|
|
||||||
find_package(zstd CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET zstd::libzstd_shared)
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_shared>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_static>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_tiff_zstd_configs "${z_vcpkg_tiff_zstd_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_tiff_zstd_configs)
|
|
||||||
get_target_property(ZSTD_LIBRARY_${z_vcpkg_config} "${z_vcpkg_tiff_zstd_target}" "${z_vcpkg_tiff_zstd_target_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(ZSTD)
|
|
||||||
if(NOT TARGET ZSTD::ZSTD)
|
|
||||||
add_library(ZSTD::ZSTD INTERFACE IMPORTED)
|
|
||||||
set_property(TARGET ZSTD::ZSTD APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_zstd})
|
|
||||||
endif()
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries ${z_vcpkg_tiff_zstd})
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZSTD_LIBRARIES})
|
|
||||||
unset(z_vcpkg_tiff_zstd)
|
|
||||||
unset(z_vcpkg_tiff_zstd_configs)
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_tiff_zstd_target)
|
|
||||||
endif()
|
|
||||||
if("@libdeflate@")
|
|
||||||
find_package(libdeflate ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET libdeflate::libdeflate_shared)
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_libdeflate_configs "${z_vcpkg_libdeflate_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_libdeflate_configs)
|
|
||||||
get_target_property(Z_VCPKG_DEFLATE_LIBRARY_${z_vcpkg_config} "${z_vcpkg_libdeflate_target}" "${z_vcpkg_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(Z_VCPKG_DEFLATE)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:${z_vcpkg_libdeflate_target}>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${Z_VCPKG_DEFLATE_LIBRARIES})
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_libdeflate_configs)
|
|
||||||
unset(z_vcpkg_libdeflate_target)
|
|
||||||
unset(z_vcpkg_property)
|
|
||||||
unset(Z_VCPKG_DEFLATE_FOUND)
|
|
||||||
endif()
|
|
||||||
if("@zlib@")
|
|
||||||
find_package(ZLIB ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:ZLIB::ZLIB>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZLIB_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(UNIX)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries m)
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(TARGET TIFF::TIFF)
|
|
||||||
set_property(TARGET TIFF::TIFF APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_link_libraries})
|
|
||||||
endif()
|
|
||||||
list(APPEND TIFF_LIBRARIES ${z_vcpkg_tiff_libraries})
|
|
||||||
unset(z_vcpkg_tiff_link_libraries)
|
|
||||||
unset(z_vcpkg_tiff_libraries)
|
|
||||||
endif()
|
|
||||||
unset(z_vcpkg_tiff_find_options)
|
|
||||||
cmake_policy(POP)
|
|
@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"version": "4.6.0",
|
|
||||||
"port-version": 2,
|
|
||||||
"description": "A library that supports the manipulation of TIFF image files",
|
|
||||||
"homepage": "https://libtiff.gitlab.io/libtiff/",
|
|
||||||
"license": "libtiff",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
"jpeg",
|
|
||||||
"zip"
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"cxx": {
|
|
||||||
"description": "Build C++ libtiffxx library"
|
|
||||||
},
|
|
||||||
"jpeg": {
|
|
||||||
"description": "Support JPEG compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libjpeg-turbo"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"libdeflate": {
|
|
||||||
"description": "Use libdeflate for faster ZIP support",
|
|
||||||
"dependencies": [
|
|
||||||
"libdeflate",
|
|
||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"default-features": false,
|
|
||||||
"features": [
|
|
||||||
"zip"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"description": "Build tools"
|
|
||||||
},
|
|
||||||
"webp": {
|
|
||||||
"description": "Support WEBP compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libwebp"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zip": {
|
|
||||||
"description": "Support ZIP/deflate compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zlib"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zstd": {
|
|
||||||
"description": "Support ZSTD compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zstd"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/SDL2Config.cmake.in b/SDL2Config.cmake.in
|
|
||||||
index cc8bcf26d..ead829767 100644
|
|
||||||
--- a/SDL2Config.cmake.in
|
|
||||||
+++ b/SDL2Config.cmake.in
|
|
||||||
@@ -35,7 +35,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/sdlfind.cmake")
|
|
||||||
|
|
||||||
set(SDL_ALSA @SDL_ALSA@)
|
|
||||||
set(SDL_ALSA_SHARED @SDL_ALSA_SHARED@)
|
|
||||||
-if(SDL_ALSA AND NOT SDL_ALSA_SHARED AND TARGET SDL2::SDL2-static)
|
|
||||||
+if(SDL_ALSA)
|
|
||||||
sdlFindALSA()
|
|
||||||
endif()
|
|
||||||
unset(SDL_ALSA)
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/sdlchecks.cmake b/cmake/sdlchecks.cmake
|
|
||||||
index 65a98efbe..2f99f28f1 100644
|
|
||||||
--- a/cmake/sdlchecks.cmake
|
|
||||||
+++ b/cmake/sdlchecks.cmake
|
|
||||||
@@ -352,7 +352,7 @@ endmacro()
|
|
||||||
# - HAVE_SDL_LOADSO opt
|
|
||||||
macro(CheckLibSampleRate)
|
|
||||||
if(SDL_LIBSAMPLERATE)
|
|
||||||
- find_package(SampleRate QUIET)
|
|
||||||
+ find_package(SampleRate CONFIG REQUIRED)
|
|
||||||
if(SampleRate_FOUND AND TARGET SampleRate::samplerate)
|
|
||||||
set(HAVE_LIBSAMPLERATE TRUE)
|
|
||||||
set(HAVE_LIBSAMPLERATE_H TRUE)
|
|
@ -1,137 +0,0 @@
|
|||||||
vcpkg_from_github(
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libsdl-org/SDL
|
|
||||||
REF "release-${VERSION}"
|
|
||||||
SHA512 c7635a83a52f3970a372b804a8631f0a7e6b8d89aed1117bcc54a2040ad0928122175004cf2b42cf84a4fd0f86236f779229eaa63dfa6ca9c89517f999c5ff1c
|
|
||||||
HEAD_REF main
|
|
||||||
PATCHES
|
|
||||||
deps.patch
|
|
||||||
alsa-dep-fix.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "static" SDL_STATIC)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_LIBRARY_LINKAGE}" "dynamic" SDL_SHARED)
|
|
||||||
string(COMPARE EQUAL "${VCPKG_CRT_LINKAGE}" "static" FORCE_STATIC_VCRT)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
alsa SDL_ALSA
|
|
||||||
alsa CMAKE_REQUIRE_FIND_PACKAGE_ALSA
|
|
||||||
ibus SDL_IBUS
|
|
||||||
samplerate SDL_LIBSAMPLERATE
|
|
||||||
vulkan SDL_VULKAN
|
|
||||||
wayland SDL_WAYLAND
|
|
||||||
x11 SDL_X11
|
|
||||||
INVERTED_FEATURES
|
|
||||||
alsa CMAKE_DISABLE_FIND_PACKAGE_ALSA
|
|
||||||
)
|
|
||||||
|
|
||||||
if ("x11" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Xorg dependencies to use feature x11:\nsudo apt install libx11-dev libxft-dev libxext-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("wayland" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install Wayland dependencies to use feature wayland:\nsudo apt install libwayland-dev libxkbcommon-dev libegl1-mesa-dev\n")
|
|
||||||
endif()
|
|
||||||
if ("ibus" IN_LIST FEATURES)
|
|
||||||
message(WARNING "You will need to install ibus dependencies to use feature ibus:\nsudo apt install libibus-1.0-dev\n")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
set(configure_opts WINDOWS_USE_MSBUILD)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
${configure_opts}
|
|
||||||
OPTIONS ${FEATURE_OPTIONS}
|
|
||||||
-DSDL_STATIC=${SDL_STATIC}
|
|
||||||
-DSDL_SHARED=${SDL_SHARED}
|
|
||||||
-DSDL_FORCE_STATIC_VCRT=${FORCE_STATIC_VCRT}
|
|
||||||
-DSDL_LIBC=ON
|
|
||||||
-DSDL_TEST=OFF
|
|
||||||
-DSDL_INSTALL_CMAKEDIR="cmake"
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_Git=ON
|
|
||||||
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON
|
|
||||||
-DSDL_LIBSAMPLERATE_SHARED=OFF
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
SDL_FORCE_STATIC_VCRT
|
|
||||||
PKG_CONFIG_USE_CMAKE_PREFIX_PATH
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
vcpkg_cmake_config_fixup(CONFIG_PATH cmake)
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin/sdl2-config"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/SDL2.framework"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/licenses"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/share/aclocal"
|
|
||||||
)
|
|
||||||
|
|
||||||
file(GLOB BINS "${CURRENT_PACKAGES_DIR}/debug/bin/*" "${CURRENT_PACKAGES_DIR}/bin/*")
|
|
||||||
if(NOT BINS)
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/bin"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/bin"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_UWP AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/lib/SDL2main.lib" "${CURRENT_PACKAGES_DIR}/lib/manual-link/SDL2main.lib")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
file(MAKE_DIRECTORY "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link")
|
|
||||||
file(RENAME "${CURRENT_PACKAGES_DIR}/debug/lib/SDL2maind.lib" "${CURRENT_PACKAGES_DIR}/debug/lib/manual-link/SDL2maind.lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
file(GLOB SHARE_FILES "${CURRENT_PACKAGES_DIR}/share/sdl2/*.cmake")
|
|
||||||
foreach(SHARE_FILE ${SHARE_FILES})
|
|
||||||
vcpkg_replace_string("${SHARE_FILE}" "lib/SDL2main" "lib/manual-link/SDL2main")
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
|
|
||||||
set(DYLIB_COMPATIBILITY_VERSION_REGEX "set\\(DYLIB_COMPATIBILITY_VERSION (.+)\\)")
|
|
||||||
set(DYLIB_CURRENT_VERSION_REGEX "set\\(DYLIB_CURRENT_VERSION (.+)\\)")
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_COMPATIBILITY_VERSION REGEX ${DYLIB_COMPATIBILITY_VERSION_REGEX})
|
|
||||||
file(STRINGS "${SOURCE_PATH}/CMakeLists.txt" DYLIB_CURRENT_VERSION REGEX ${DYLIB_CURRENT_VERSION_REGEX})
|
|
||||||
string(REGEX REPLACE ${DYLIB_COMPATIBILITY_VERSION_REGEX} "\\1" DYLIB_COMPATIBILITY_VERSION "${DYLIB_COMPATIBILITY_VERSION}")
|
|
||||||
string(REGEX REPLACE ${DYLIB_CURRENT_VERSION_REGEX} "\\1" DYLIB_CURRENT_VERSION "${DYLIB_CURRENT_VERSION}")
|
|
||||||
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2main" "-lSDL2maind")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2 " "-lSDL2d ")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-static " "-lSDL2-staticd ")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "dynamic" AND VCPKG_TARGET_IS_WINDOWS AND NOT VCPKG_TARGET_IS_MINGW)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-lSDL2-static " " ")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-lSDL2-staticd " " ")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(VCPKG_TARGET_IS_UWP)
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "release")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
if(NOT DEFINED VCPKG_BUILD_TYPE OR VCPKG_BUILD_TYPE STREQUAL "debug")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "$<$<CONFIG:Debug>:d>.lib" "d")
|
|
||||||
vcpkg_replace_string("${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/sdl2.pc" "-l-nodefaultlib:" "-nodefaultlib:")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(INSTALL "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.txt")
|
|
@ -1,8 +0,0 @@
|
|||||||
sdl2 provides CMake targets:
|
|
||||||
|
|
||||||
find_package(SDL2 CONFIG REQUIRED)
|
|
||||||
target_link_libraries(main
|
|
||||||
PRIVATE
|
|
||||||
$<TARGET_NAME_IF_EXISTS:SDL2::SDL2main>
|
|
||||||
$<IF:$<TARGET_EXISTS:SDL2::SDL2>,SDL2::SDL2,SDL2::SDL2-static>
|
|
||||||
)
|
|
@ -1,68 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "sdl2",
|
|
||||||
"version": "2.30.0",
|
|
||||||
"description": "Simple DirectMedia Layer is a cross-platform development library designed to provide low level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.",
|
|
||||||
"homepage": "https://www.libsdl.org/download-2.0.php",
|
|
||||||
"license": "Zlib",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "dbus",
|
|
||||||
"default-features": false,
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
{
|
|
||||||
"name": "ibus",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "wayland",
|
|
||||||
"platform": "linux"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "x11",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"alsa": {
|
|
||||||
"description": "Support for alsa audio",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "alsa",
|
|
||||||
"platform": "linux"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"ibus": {
|
|
||||||
"description": "Build with ibus IME support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"samplerate": {
|
|
||||||
"description": "Use libsamplerate for audio rate conversion",
|
|
||||||
"dependencies": [
|
|
||||||
"libsamplerate"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"vulkan": {
|
|
||||||
"description": "Vulkan functionality for SDL"
|
|
||||||
},
|
|
||||||
"wayland": {
|
|
||||||
"description": "Build with Wayland support",
|
|
||||||
"supports": "linux"
|
|
||||||
},
|
|
||||||
"x11": {
|
|
||||||
"description": "Build with X11 support",
|
|
||||||
"supports": "!windows"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
diff --git a/cmake/FindCMath.cmake b/cmake/FindCMath.cmake
|
|
||||||
index ad92218..dd42aba 100644
|
|
||||||
--- a/cmake/FindCMath.cmake
|
|
||||||
+++ b/cmake/FindCMath.cmake
|
|
||||||
@@ -31,7 +31,7 @@ include(CheckSymbolExists)
|
|
||||||
include(CheckLibraryExists)
|
|
||||||
|
|
||||||
check_symbol_exists(pow "math.h" CMath_HAVE_LIBC_POW)
|
|
||||||
-find_library(CMath_LIBRARY NAMES m)
|
|
||||||
+find_library(CMath_LIBRARY NAMES m PATHS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
|
||||||
|
|
||||||
if(NOT CMath_HAVE_LIBC_POW)
|
|
||||||
set(CMAKE_REQUIRED_LIBRARIES_SAVE ${CMAKE_REQUIRED_LIBRARIES})
|
|
@ -1,86 +0,0 @@
|
|||||||
vcpkg_from_gitlab(
|
|
||||||
GITLAB_URL https://gitlab.com
|
|
||||||
OUT_SOURCE_PATH SOURCE_PATH
|
|
||||||
REPO libtiff/libtiff
|
|
||||||
REF "v${VERSION}"
|
|
||||||
SHA512 ef2f1d424219d9e245069b7d23e78f5e817cf6ee516d46694915ab6c8909522166f84997513d20a702f4e52c3f18467813935b328fafa34bea5156dee00f66fa
|
|
||||||
HEAD_REF master
|
|
||||||
PATCHES
|
|
||||||
FindCMath.patch
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_check_features(OUT_FEATURE_OPTIONS FEATURE_OPTIONS
|
|
||||||
FEATURES
|
|
||||||
cxx cxx
|
|
||||||
jpeg jpeg
|
|
||||||
jpeg CMAKE_REQUIRE_FIND_PACKAGE_JPEG
|
|
||||||
libdeflate libdeflate
|
|
||||||
libdeflate CMAKE_REQUIRE_FIND_PACKAGE_Deflate
|
|
||||||
lzma lzma
|
|
||||||
lzma CMAKE_REQUIRE_FIND_PACKAGE_liblzma
|
|
||||||
tools tiff-tools
|
|
||||||
webp webp
|
|
||||||
webp CMAKE_REQUIRE_FIND_PACKAGE_WebP
|
|
||||||
zip zlib
|
|
||||||
zip CMAKE_REQUIRE_FIND_PACKAGE_ZLIB
|
|
||||||
zstd zstd
|
|
||||||
zstd CMAKE_REQUIRE_FIND_PACKAGE_ZSTD
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_configure(
|
|
||||||
SOURCE_PATH "${SOURCE_PATH}"
|
|
||||||
OPTIONS
|
|
||||||
${FEATURE_OPTIONS}
|
|
||||||
-DCMAKE_FIND_PACKAGE_PREFER_CONFIG=ON
|
|
||||||
-Dtiff-docs=OFF
|
|
||||||
-Dtiff-contrib=OFF
|
|
||||||
-Dtiff-tests=OFF
|
|
||||||
-Djbig=OFF # This is disabled by default due to GPL/Proprietary licensing.
|
|
||||||
-Djpeg12=OFF
|
|
||||||
-Dlerc=OFF
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_OpenGL=ON
|
|
||||||
-DCMAKE_DISABLE_FIND_PACKAGE_GLUT=ON
|
|
||||||
-DZSTD_HAVE_DECOMPRESS_STREAM=ON
|
|
||||||
-DHAVE_JPEGTURBO_DUAL_MODE_8_12=OFF
|
|
||||||
OPTIONS_DEBUG
|
|
||||||
-DCMAKE_DEBUG_POSTFIX=d # tiff sets "d" for MSVC only.
|
|
||||||
MAYBE_UNUSED_VARIABLES
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_GLUT
|
|
||||||
CMAKE_DISABLE_FIND_PACKAGE_OpenGL
|
|
||||||
ZSTD_HAVE_DECOMPRESS_STREAM
|
|
||||||
)
|
|
||||||
|
|
||||||
vcpkg_cmake_install()
|
|
||||||
|
|
||||||
# CMake config wasn't packaged in the past and is not yet usable now,
|
|
||||||
# cf. https://gitlab.com/libtiff/libtiff/-/merge_requests/496
|
|
||||||
# vcpkg_cmake_config_fixup(CONFIG_PATH "lib/cmake/tiff")
|
|
||||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/lib/cmake" "${CURRENT_PACKAGES_DIR}/debug/lib/cmake")
|
|
||||||
|
|
||||||
set(_file "${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig/libtiff-4.pc")
|
|
||||||
if(EXISTS "${_file}")
|
|
||||||
vcpkg_replace_string("${_file}" "-ltiff" "-ltiffd")
|
|
||||||
endif()
|
|
||||||
vcpkg_fixup_pkgconfig()
|
|
||||||
|
|
||||||
file(REMOVE_RECURSE
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/include"
|
|
||||||
"${CURRENT_PACKAGES_DIR}/debug/share"
|
|
||||||
)
|
|
||||||
|
|
||||||
configure_file("${CMAKE_CURRENT_LIST_DIR}/vcpkg-cmake-wrapper.cmake.in" "${CURRENT_PACKAGES_DIR}/share/${PORT}/vcpkg-cmake-wrapper.cmake" @ONLY)
|
|
||||||
|
|
||||||
if ("tools" IN_LIST FEATURES)
|
|
||||||
vcpkg_copy_tools(TOOL_NAMES
|
|
||||||
tiffcp
|
|
||||||
tiffdump
|
|
||||||
tiffinfo
|
|
||||||
tiffset
|
|
||||||
tiffsplit
|
|
||||||
AUTO_CLEAN
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
vcpkg_copy_pdbs()
|
|
||||||
file(COPY "${CURRENT_PORT_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
|
||||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE.md")
|
|
@ -1,9 +0,0 @@
|
|||||||
tiff is compatible with built-in CMake targets:
|
|
||||||
|
|
||||||
find_package(TIFF REQUIRED)
|
|
||||||
target_link_libraries(main PRIVATE TIFF::TIFF)
|
|
||||||
|
|
||||||
tiff provides pkg-config modules:
|
|
||||||
|
|
||||||
# Tag Image File Format (TIFF) library.
|
|
||||||
libtiff-4
|
|
@ -1,104 +0,0 @@
|
|||||||
cmake_policy(PUSH)
|
|
||||||
cmake_policy(SET CMP0012 NEW)
|
|
||||||
cmake_policy(SET CMP0057 NEW)
|
|
||||||
set(z_vcpkg_tiff_find_options "")
|
|
||||||
if("REQUIRED" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "REQUIRED")
|
|
||||||
endif()
|
|
||||||
if("QUIET" IN_LIST ARGS)
|
|
||||||
list(APPEND z_vcpkg_tiff_find_options "QUIET")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
_find_package(${ARGS})
|
|
||||||
|
|
||||||
if(TIFF_FOUND AND "@VCPKG_LIBRARY_LINKAGE@" STREQUAL "static")
|
|
||||||
include(SelectLibraryConfigurations)
|
|
||||||
set(z_vcpkg_tiff_link_libraries "")
|
|
||||||
set(z_vcpkg_tiff_libraries "")
|
|
||||||
if("@webp@")
|
|
||||||
find_package(WebP CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:WebP::WebP>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${WebP_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@lzma@")
|
|
||||||
find_package(LibLZMA ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:LibLZMA::LibLZMA>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${LIBLZMA_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@jpeg@")
|
|
||||||
find_package(JPEG ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:JPEG::JPEG>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${JPEG_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if("@zstd@")
|
|
||||||
find_package(zstd CONFIG ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET zstd::libzstd_shared)
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_shared>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_tiff_zstd_target_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_tiff_zstd "\$<LINK_ONLY:zstd::libzstd_static>")
|
|
||||||
set(z_vcpkg_tiff_zstd_target zstd::libzstd_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_tiff_zstd_configs "${z_vcpkg_tiff_zstd_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_tiff_zstd_configs)
|
|
||||||
get_target_property(ZSTD_LIBRARY_${z_vcpkg_config} "${z_vcpkg_tiff_zstd_target}" "${z_vcpkg_tiff_zstd_target_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(ZSTD)
|
|
||||||
if(NOT TARGET ZSTD::ZSTD)
|
|
||||||
add_library(ZSTD::ZSTD INTERFACE IMPORTED)
|
|
||||||
set_property(TARGET ZSTD::ZSTD APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_zstd})
|
|
||||||
endif()
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries ${z_vcpkg_tiff_zstd})
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZSTD_LIBRARIES})
|
|
||||||
unset(z_vcpkg_tiff_zstd)
|
|
||||||
unset(z_vcpkg_tiff_zstd_configs)
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_tiff_zstd_target)
|
|
||||||
endif()
|
|
||||||
if("@libdeflate@")
|
|
||||||
find_package(libdeflate ${z_vcpkg_tiff_find_options})
|
|
||||||
set(z_vcpkg_property "IMPORTED_LOCATION_")
|
|
||||||
if(TARGET libdeflate::libdeflate_shared)
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_shared)
|
|
||||||
if(WIN32)
|
|
||||||
set(z_vcpkg_property "IMPORTED_IMPLIB_")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(z_vcpkg_libdeflate_target libdeflate::libdeflate_static)
|
|
||||||
endif()
|
|
||||||
get_target_property(z_vcpkg_libdeflate_configs "${z_vcpkg_libdeflate_target}" IMPORTED_CONFIGURATIONS)
|
|
||||||
foreach(z_vcpkg_config IN LISTS z_vcpkg_libdeflate_configs)
|
|
||||||
get_target_property(Z_VCPKG_DEFLATE_LIBRARY_${z_vcpkg_config} "${z_vcpkg_libdeflate_target}" "${z_vcpkg_property}${z_vcpkg_config}")
|
|
||||||
endforeach()
|
|
||||||
select_library_configurations(Z_VCPKG_DEFLATE)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:${z_vcpkg_libdeflate_target}>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${Z_VCPKG_DEFLATE_LIBRARIES})
|
|
||||||
unset(z_vcpkg_config)
|
|
||||||
unset(z_vcpkg_libdeflate_configs)
|
|
||||||
unset(z_vcpkg_libdeflate_target)
|
|
||||||
unset(z_vcpkg_property)
|
|
||||||
unset(Z_VCPKG_DEFLATE_FOUND)
|
|
||||||
endif()
|
|
||||||
if("@zlib@")
|
|
||||||
find_package(ZLIB ${z_vcpkg_tiff_find_options})
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries "\$<LINK_ONLY:ZLIB::ZLIB>")
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries ${ZLIB_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
if(UNIX)
|
|
||||||
list(APPEND z_vcpkg_tiff_link_libraries m)
|
|
||||||
list(APPEND z_vcpkg_tiff_libraries m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(TARGET TIFF::TIFF)
|
|
||||||
set_property(TARGET TIFF::TIFF APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${z_vcpkg_tiff_link_libraries})
|
|
||||||
endif()
|
|
||||||
list(APPEND TIFF_LIBRARIES ${z_vcpkg_tiff_libraries})
|
|
||||||
unset(z_vcpkg_tiff_link_libraries)
|
|
||||||
unset(z_vcpkg_tiff_libraries)
|
|
||||||
endif()
|
|
||||||
unset(z_vcpkg_tiff_find_options)
|
|
||||||
cmake_policy(POP)
|
|
@ -1,67 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"version": "4.6.0",
|
|
||||||
"port-version": 2,
|
|
||||||
"description": "A library that supports the manipulation of TIFF image files",
|
|
||||||
"homepage": "https://libtiff.gitlab.io/libtiff/",
|
|
||||||
"license": "libtiff",
|
|
||||||
"dependencies": [
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake",
|
|
||||||
"host": true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "vcpkg-cmake-config",
|
|
||||||
"host": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"default-features": [
|
|
||||||
"jpeg",
|
|
||||||
"zip"
|
|
||||||
],
|
|
||||||
"features": {
|
|
||||||
"cxx": {
|
|
||||||
"description": "Build C++ libtiffxx library"
|
|
||||||
},
|
|
||||||
"jpeg": {
|
|
||||||
"description": "Support JPEG compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libjpeg-turbo"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"libdeflate": {
|
|
||||||
"description": "Use libdeflate for faster ZIP support",
|
|
||||||
"dependencies": [
|
|
||||||
"libdeflate",
|
|
||||||
{
|
|
||||||
"name": "tiff",
|
|
||||||
"default-features": false,
|
|
||||||
"features": [
|
|
||||||
"zip"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"tools": {
|
|
||||||
"description": "Build tools"
|
|
||||||
},
|
|
||||||
"webp": {
|
|
||||||
"description": "Support WEBP compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"libwebp"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zip": {
|
|
||||||
"description": "Support ZIP/deflate compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zlib"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"zstd": {
|
|
||||||
"description": "Support ZSTD compression in TIFF image files",
|
|
||||||
"dependencies": [
|
|
||||||
"zstd"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
6
dist/linux/appimage.sh
vendored
6
dist/linux/appimage.sh
vendored
@ -10,6 +10,8 @@ curl -sSfL https://github.com"$(curl https://github.com/probonopd/go-appimage/re
|
|||||||
chmod a+x mkappimage.AppImage
|
chmod a+x mkappimage.AppImage
|
||||||
curl -sSfLO "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
|
curl -sSfLO "https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh"
|
||||||
chmod a+x linuxdeploy-plugin-gtk.sh
|
chmod a+x linuxdeploy-plugin-gtk.sh
|
||||||
|
curl -sSfLO "https://github.com/darealshinji/linuxdeploy-plugin-checkrt/releases/download/continuous/linuxdeploy-plugin-checkrt.sh"
|
||||||
|
chmod a+x linuxdeploy-plugin-checkrt.sh
|
||||||
|
|
||||||
if [[ ! -e /usr/lib/x86_64-linux-gnu ]]; then
|
if [[ ! -e /usr/lib/x86_64-linux-gnu ]]; then
|
||||||
sed -i 's#lib\/x86_64-linux-gnu#lib64#g' linuxdeploy-plugin-gtk.sh
|
sed -i 's#lib\/x86_64-linux-gnu#lib64#g' linuxdeploy-plugin-gtk.sh
|
||||||
@ -39,7 +41,8 @@ export NO_STRIP=1
|
|||||||
-d "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.desktop \
|
-d "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.desktop \
|
||||||
-i "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.png \
|
-i "${GITHUB_WORKSPACE}"/AppDir/info.cemu.Cemu.png \
|
||||||
-e "${GITHUB_WORKSPACE}"/AppDir/usr/bin/Cemu \
|
-e "${GITHUB_WORKSPACE}"/AppDir/usr/bin/Cemu \
|
||||||
--plugin gtk
|
--plugin gtk \
|
||||||
|
--plugin checkrt
|
||||||
|
|
||||||
if ! GITVERSION="$(git rev-parse --short HEAD 2>/dev/null)"; then
|
if ! GITVERSION="$(git rev-parse --short HEAD 2>/dev/null)"; then
|
||||||
GITVERSION=experimental
|
GITVERSION=experimental
|
||||||
@ -47,7 +50,6 @@ fi
|
|||||||
echo "Cemu Version Cemu-${GITVERSION}"
|
echo "Cemu Version Cemu-${GITVERSION}"
|
||||||
|
|
||||||
rm AppDir/usr/lib/libwayland-client.so.0
|
rm AppDir/usr/lib/libwayland-client.so.0
|
||||||
cp /lib/x86_64-linux-gnu/libstdc++.so.6 AppDir/usr/lib/
|
|
||||||
echo -e "export LC_ALL=C\nexport FONTCONFIG_PATH=/etc/fonts" >> AppDir/apprun-hooks/linuxdeploy-plugin-gtk.sh
|
echo -e "export LC_ALL=C\nexport FONTCONFIG_PATH=/etc/fonts" >> AppDir/apprun-hooks/linuxdeploy-plugin-gtk.sh
|
||||||
VERSION="${GITVERSION}" ./mkappimage.AppImage --appimage-extract-and-run "${GITHUB_WORKSPACE}"/AppDir
|
VERSION="${GITVERSION}" ./mkappimage.AppImage --appimage-extract-and-run "${GITHUB_WORKSPACE}"/AppDir
|
||||||
|
|
||||||
|
@ -56,6 +56,12 @@ add_executable(CemuBin
|
|||||||
mainLLE.cpp
|
mainLLE.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MSVC AND MSVC_VERSION EQUAL 1940)
|
||||||
|
# workaround for an msvc issue on VS 17.10 where generated ILK files are too large
|
||||||
|
# see https://developercommunity.visualstudio.com/t/After-updating-to-VS-1710-the-size-of-/10665511
|
||||||
|
set_target_properties(CemuBin PROPERTIES LINK_FLAGS "/INCREMENTAL:NO")
|
||||||
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
target_sources(CemuBin PRIVATE
|
target_sources(CemuBin PRIVATE
|
||||||
resource/cemu.rc
|
resource/cemu.rc
|
||||||
@ -100,7 +106,7 @@ if (MACOS_BUNDLE)
|
|||||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_BINARY_DIR}/vcpkg_installed/x64-osx/lib/libusb-1.0.0.dylib" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libusb-1.0.0.dylib"
|
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_BINARY_DIR}/vcpkg_installed/x64-osx/lib/libusb-1.0.0.dylib" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/Frameworks/libusb-1.0.0.dylib"
|
||||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_SOURCE_DIR}/src/resource/update.sh" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/update.sh"
|
COMMAND ${CMAKE_COMMAND} ARGS -E copy "${CMAKE_SOURCE_DIR}/src/resource/update.sh" "${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/update.sh"
|
||||||
COMMAND bash -c "install_name_tool -add_rpath @executable_path/../Frameworks ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}"
|
COMMAND bash -c "install_name_tool -add_rpath @executable_path/../Frameworks ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}"
|
||||||
COMMAND bash -c "install_name_tool -change /usr/local/opt/libusb/lib/libusb-1.0.0.dylib @executable_path/../Frameworks/libusb-1.0.0.dylib ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}")
|
COMMAND bash -c "install_name_tool -change /Users/runner/work/Cemu/Cemu/build/vcpkg_installed/x64-osx/lib/libusb-1.0.0.dylib @executable_path/../Frameworks/libusb-1.0.0.dylib ${CMAKE_SOURCE_DIR}/bin/${OUTPUT_NAME}.app/Contents/MacOS/${OUTPUT_NAME}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set_target_properties(CemuBin PROPERTIES
|
set_target_properties(CemuBin PROPERTIES
|
||||||
|
@ -218,6 +218,8 @@ add_library(CemuCafe
|
|||||||
HW/SI/SI.cpp
|
HW/SI/SI.cpp
|
||||||
HW/SI/si.h
|
HW/SI/si.h
|
||||||
HW/VI/VI.cpp
|
HW/VI/VI.cpp
|
||||||
|
IOSU/ccr_nfc/iosu_ccr_nfc.cpp
|
||||||
|
IOSU/ccr_nfc/iosu_ccr_nfc.h
|
||||||
IOSU/fsa/fsa_types.h
|
IOSU/fsa/fsa_types.h
|
||||||
IOSU/fsa/iosu_fsa.cpp
|
IOSU/fsa/iosu_fsa.cpp
|
||||||
IOSU/fsa/iosu_fsa.h
|
IOSU/fsa/iosu_fsa.h
|
||||||
@ -372,12 +374,24 @@ add_library(CemuCafe
|
|||||||
OS/libs/gx2/GX2_Texture.h
|
OS/libs/gx2/GX2_Texture.h
|
||||||
OS/libs/gx2/GX2_TilingAperture.cpp
|
OS/libs/gx2/GX2_TilingAperture.cpp
|
||||||
OS/libs/h264_avc/H264Dec.cpp
|
OS/libs/h264_avc/H264Dec.cpp
|
||||||
|
OS/libs/h264_avc/H264DecBackendAVC.cpp
|
||||||
OS/libs/h264_avc/h264dec.h
|
OS/libs/h264_avc/h264dec.h
|
||||||
|
OS/libs/h264_avc/H264DecInternal.h
|
||||||
OS/libs/h264_avc/parser
|
OS/libs/h264_avc/parser
|
||||||
OS/libs/h264_avc/parser/H264Parser.cpp
|
OS/libs/h264_avc/parser/H264Parser.cpp
|
||||||
OS/libs/h264_avc/parser/H264Parser.h
|
OS/libs/h264_avc/parser/H264Parser.h
|
||||||
OS/libs/mic/mic.cpp
|
OS/libs/mic/mic.cpp
|
||||||
OS/libs/mic/mic.h
|
OS/libs/mic/mic.h
|
||||||
|
OS/libs/nfc/ndef.cpp
|
||||||
|
OS/libs/nfc/ndef.h
|
||||||
|
OS/libs/nfc/nfc.cpp
|
||||||
|
OS/libs/nfc/nfc.h
|
||||||
|
OS/libs/nfc/stream.cpp
|
||||||
|
OS/libs/nfc/stream.h
|
||||||
|
OS/libs/nfc/TagV0.cpp
|
||||||
|
OS/libs/nfc/TagV0.h
|
||||||
|
OS/libs/nfc/TLV.cpp
|
||||||
|
OS/libs/nfc/TLV.h
|
||||||
OS/libs/nlibcurl/nlibcurl.cpp
|
OS/libs/nlibcurl/nlibcurl.cpp
|
||||||
OS/libs/nlibcurl/nlibcurlDebug.hpp
|
OS/libs/nlibcurl/nlibcurlDebug.hpp
|
||||||
OS/libs/nlibcurl/nlibcurl.h
|
OS/libs/nlibcurl/nlibcurl.h
|
||||||
@ -445,14 +459,22 @@ add_library(CemuCafe
|
|||||||
OS/libs/nsyshid/AttachDefaultBackends.cpp
|
OS/libs/nsyshid/AttachDefaultBackends.cpp
|
||||||
OS/libs/nsyshid/Whitelist.cpp
|
OS/libs/nsyshid/Whitelist.cpp
|
||||||
OS/libs/nsyshid/Whitelist.h
|
OS/libs/nsyshid/Whitelist.h
|
||||||
|
OS/libs/nsyshid/BackendEmulated.cpp
|
||||||
|
OS/libs/nsyshid/BackendEmulated.h
|
||||||
OS/libs/nsyshid/BackendLibusb.cpp
|
OS/libs/nsyshid/BackendLibusb.cpp
|
||||||
OS/libs/nsyshid/BackendLibusb.h
|
OS/libs/nsyshid/BackendLibusb.h
|
||||||
OS/libs/nsyshid/BackendWindowsHID.cpp
|
OS/libs/nsyshid/BackendWindowsHID.cpp
|
||||||
OS/libs/nsyshid/BackendWindowsHID.h
|
OS/libs/nsyshid/BackendWindowsHID.h
|
||||||
|
OS/libs/nsyshid/Infinity.cpp
|
||||||
|
OS/libs/nsyshid/Infinity.h
|
||||||
|
OS/libs/nsyshid/Skylander.cpp
|
||||||
|
OS/libs/nsyshid/Skylander.h
|
||||||
OS/libs/nsyskbd/nsyskbd.cpp
|
OS/libs/nsyskbd/nsyskbd.cpp
|
||||||
OS/libs/nsyskbd/nsyskbd.h
|
OS/libs/nsyskbd/nsyskbd.h
|
||||||
OS/libs/nsysnet/nsysnet.cpp
|
OS/libs/nsysnet/nsysnet.cpp
|
||||||
OS/libs/nsysnet/nsysnet.h
|
OS/libs/nsysnet/nsysnet.h
|
||||||
|
OS/libs/ntag/ntag.cpp
|
||||||
|
OS/libs/ntag/ntag.h
|
||||||
OS/libs/padscore/padscore.cpp
|
OS/libs/padscore/padscore.cpp
|
||||||
OS/libs/padscore/padscore.h
|
OS/libs/padscore/padscore.h
|
||||||
OS/libs/proc_ui/proc_ui.cpp
|
OS/libs/proc_ui/proc_ui.cpp
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "Cafe/IOSU/legacy/iosu_boss.h"
|
#include "Cafe/IOSU/legacy/iosu_boss.h"
|
||||||
#include "Cafe/IOSU/legacy/iosu_nim.h"
|
#include "Cafe/IOSU/legacy/iosu_nim.h"
|
||||||
#include "Cafe/IOSU/PDM/iosu_pdm.h"
|
#include "Cafe/IOSU/PDM/iosu_pdm.h"
|
||||||
|
#include "Cafe/IOSU/ccr_nfc/iosu_ccr_nfc.h"
|
||||||
|
|
||||||
// IOSU initializer functions
|
// IOSU initializer functions
|
||||||
#include "Cafe/IOSU/kernel/iosu_kernel.h"
|
#include "Cafe/IOSU/kernel/iosu_kernel.h"
|
||||||
@ -51,6 +52,8 @@
|
|||||||
#include "Cafe/OS/libs/gx2/GX2.h"
|
#include "Cafe/OS/libs/gx2/GX2.h"
|
||||||
#include "Cafe/OS/libs/gx2/GX2_Misc.h"
|
#include "Cafe/OS/libs/gx2/GX2_Misc.h"
|
||||||
#include "Cafe/OS/libs/mic/mic.h"
|
#include "Cafe/OS/libs/mic/mic.h"
|
||||||
|
#include "Cafe/OS/libs/nfc/nfc.h"
|
||||||
|
#include "Cafe/OS/libs/ntag/ntag.h"
|
||||||
#include "Cafe/OS/libs/nn_aoc/nn_aoc.h"
|
#include "Cafe/OS/libs/nn_aoc/nn_aoc.h"
|
||||||
#include "Cafe/OS/libs/nn_pdm/nn_pdm.h"
|
#include "Cafe/OS/libs/nn_pdm/nn_pdm.h"
|
||||||
#include "Cafe/OS/libs/nn_cmpt/nn_cmpt.h"
|
#include "Cafe/OS/libs/nn_cmpt/nn_cmpt.h"
|
||||||
@ -533,6 +536,7 @@ namespace CafeSystem
|
|||||||
iosu::acp::GetModule(),
|
iosu::acp::GetModule(),
|
||||||
iosu::fpd::GetModule(),
|
iosu::fpd::GetModule(),
|
||||||
iosu::pdm::GetModule(),
|
iosu::pdm::GetModule(),
|
||||||
|
iosu::ccr_nfc::GetModule(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// initialize all subsystems which are persistent and don't depend on a game running
|
// initialize all subsystems which are persistent and don't depend on a game running
|
||||||
@ -587,6 +591,8 @@ namespace CafeSystem
|
|||||||
H264::Initialize();
|
H264::Initialize();
|
||||||
snd_core::Initialize();
|
snd_core::Initialize();
|
||||||
mic::Initialize();
|
mic::Initialize();
|
||||||
|
nfc::Initialize();
|
||||||
|
ntag::Initialize();
|
||||||
// init hardware register interfaces
|
// init hardware register interfaces
|
||||||
HW_SI::Initialize();
|
HW_SI::Initialize();
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
|
#include "../fsc.h"
|
||||||
|
|
||||||
// path parser and utility class for Wii U paths
|
// path parser and utility class for Wii U paths
|
||||||
// optimized to be allocation-free for common path lengths
|
// optimized to be allocation-free for common path lengths
|
||||||
class FSCPath
|
class FSCPath
|
||||||
@ -119,9 +121,7 @@ public:
|
|||||||
template<typename F>
|
template<typename F>
|
||||||
class FSAFileTree
|
class FSAFileTree
|
||||||
{
|
{
|
||||||
public:
|
private:
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
enum NODETYPE : uint8
|
enum NODETYPE : uint8
|
||||||
{
|
{
|
||||||
@ -133,6 +133,7 @@ private:
|
|||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<node_t*> subnodes;
|
std::vector<node_t*> subnodes;
|
||||||
|
size_t fileSize;
|
||||||
F* custom;
|
F* custom;
|
||||||
NODETYPE type;
|
NODETYPE type;
|
||||||
};
|
};
|
||||||
@ -179,13 +180,54 @@ private:
|
|||||||
return newNode;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DirectoryIterator : public FSCVirtualFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DirectoryIterator(node_t* node)
|
||||||
|
: m_node(node), m_subnodeIndex(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 fscGetType() override
|
||||||
|
{
|
||||||
|
return FSC_TYPE_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fscDirNext(FSCDirEntry* dirEntry) override
|
||||||
|
{
|
||||||
|
if (m_subnodeIndex >= m_node->subnodes.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const node_t* subnode = m_node->subnodes[m_subnodeIndex];
|
||||||
|
|
||||||
|
strncpy(dirEntry->path, subnode->name.c_str(), sizeof(dirEntry->path) - 1);
|
||||||
|
dirEntry->path[sizeof(dirEntry->path) - 1] = '\0';
|
||||||
|
dirEntry->isDirectory = subnode->type == FSAFileTree::NODETYPE_DIRECTORY;
|
||||||
|
dirEntry->isFile = subnode->type == FSAFileTree::NODETYPE_FILE;
|
||||||
|
dirEntry->fileSize = subnode->type == FSAFileTree::NODETYPE_FILE ? subnode->fileSize : 0;
|
||||||
|
|
||||||
|
++m_subnodeIndex;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fscRewindDir() override
|
||||||
|
{
|
||||||
|
m_subnodeIndex = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
node_t* m_node;
|
||||||
|
size_t m_subnodeIndex;
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FSAFileTree()
|
FSAFileTree()
|
||||||
{
|
{
|
||||||
rootNode.type = NODETYPE_DIRECTORY;
|
rootNode.type = NODETYPE_DIRECTORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool addFile(std::string_view path, F* custom)
|
bool addFile(std::string_view path, size_t fileSize, F* custom)
|
||||||
{
|
{
|
||||||
FSCPath p(path);
|
FSCPath p(path);
|
||||||
if (p.GetNodeCount() == 0)
|
if (p.GetNodeCount() == 0)
|
||||||
@ -196,6 +238,7 @@ public:
|
|||||||
return false; // node already exists
|
return false; // node already exists
|
||||||
// add file node
|
// add file node
|
||||||
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
|
node_t* fileNode = newNode(directoryNode, NODETYPE_FILE, p.GetNodeName(p.GetNodeCount() - 1));
|
||||||
|
fileNode->fileSize = fileSize;
|
||||||
fileNode->custom = custom;
|
fileNode->custom = custom;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -214,6 +257,20 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool getDirectory(std::string_view path, FSCVirtualFile*& dirIterator)
|
||||||
|
{
|
||||||
|
FSCPath p(path);
|
||||||
|
if (p.GetNodeCount() == 0)
|
||||||
|
return false;
|
||||||
|
node_t* node = getByNodePath(p, p.GetNodeCount(), false);
|
||||||
|
if (node == nullptr)
|
||||||
|
return false;
|
||||||
|
if (node->type != NODETYPE_DIRECTORY)
|
||||||
|
return false;
|
||||||
|
dirIterator = new DirectoryIterator(node);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool removeFile(std::string_view path)
|
bool removeFile(std::string_view path)
|
||||||
{
|
{
|
||||||
FSCPath p(path);
|
FSCPath p(path);
|
||||||
|
@ -212,4 +212,4 @@ bool FSCDeviceHostFS_Mount(std::string_view mountPath, std::string_view hostTarg
|
|||||||
|
|
||||||
// redirect device
|
// redirect device
|
||||||
void fscDeviceRedirect_map();
|
void fscDeviceRedirect_map();
|
||||||
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority);
|
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority);
|
||||||
|
@ -11,7 +11,7 @@ struct RedirectEntry
|
|||||||
|
|
||||||
FSAFileTree<RedirectEntry> redirectTree;
|
FSAFileTree<RedirectEntry> redirectTree;
|
||||||
|
|
||||||
void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& targetFilePath, sint32 priority)
|
void fscDeviceRedirect_add(std::string_view virtualSourcePath, size_t fileSize, const fs::path& targetFilePath, sint32 priority)
|
||||||
{
|
{
|
||||||
// check if source already has a redirection
|
// check if source already has a redirection
|
||||||
RedirectEntry* existingEntry;
|
RedirectEntry* existingEntry;
|
||||||
@ -24,7 +24,7 @@ void fscDeviceRedirect_add(std::string_view virtualSourcePath, const fs::path& t
|
|||||||
delete existingEntry;
|
delete existingEntry;
|
||||||
}
|
}
|
||||||
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
|
RedirectEntry* entry = new RedirectEntry(targetFilePath, priority);
|
||||||
redirectTree.addFile(virtualSourcePath, entry);
|
redirectTree.addFile(virtualSourcePath, fileSize, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
class fscDeviceTypeRedirect : public fscDeviceC
|
class fscDeviceTypeRedirect : public fscDeviceC
|
||||||
@ -32,8 +32,15 @@ class fscDeviceTypeRedirect : public fscDeviceC
|
|||||||
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
|
FSCVirtualFile* fscDeviceOpenByPath(std::string_view path, FSC_ACCESS_FLAG accessFlags, void* ctx, sint32* fscStatus) override
|
||||||
{
|
{
|
||||||
RedirectEntry* redirectionEntry;
|
RedirectEntry* redirectionEntry;
|
||||||
if (redirectTree.getFile(path, redirectionEntry))
|
|
||||||
|
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_FILE) && redirectTree.getFile(path, redirectionEntry))
|
||||||
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
|
return FSCVirtualFile_Host::OpenFile(redirectionEntry->dstPath, accessFlags, *fscStatus);
|
||||||
|
|
||||||
|
FSCVirtualFile* dirIterator;
|
||||||
|
|
||||||
|
if (HAS_FLAG(accessFlags, FSC_ACCESS_FLAG::OPEN_DIR) && redirectTree.getDirectory(path, dirIterator))
|
||||||
|
return dirIterator;
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,7 +830,7 @@ void GraphicPack2::_iterateReplacedFiles(const fs::path& currentPath, bool isAOC
|
|||||||
{
|
{
|
||||||
virtualMountPath = fs::path("vol/content/") / virtualMountPath;
|
virtualMountPath = fs::path("vol/content/") / virtualMountPath;
|
||||||
}
|
}
|
||||||
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.path().generic_string(), m_fs_priority);
|
fscDeviceRedirect_add(virtualMountPath.generic_string(), it.file_size(), it.path().generic_string(), m_fs_priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,8 +501,6 @@ void debugger_createPPCStateSnapshot(PPCInterpreter_t* hCPU)
|
|||||||
debuggerState.debugSession.ppcSnapshot.cr[i] = hCPU->cr[i];
|
debuggerState.debugSession.ppcSnapshot.cr[i] = hCPU->cr[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLogStackTrace(OSThread_t* thread, MPTR sp);
|
|
||||||
|
|
||||||
void debugger_enterTW(PPCInterpreter_t* hCPU)
|
void debugger_enterTW(PPCInterpreter_t* hCPU)
|
||||||
{
|
{
|
||||||
// handle logging points
|
// handle logging points
|
||||||
|
@ -212,11 +212,12 @@ static void PPCInterpreter_SUBF(PPCInterpreter_t* hCPU, uint32 opcode)
|
|||||||
|
|
||||||
static void PPCInterpreter_SUBFO(PPCInterpreter_t* hCPU, uint32 opcode)
|
static void PPCInterpreter_SUBFO(PPCInterpreter_t* hCPU, uint32 opcode)
|
||||||
{
|
{
|
||||||
// untested (Don't Starve Giant Edition uses this)
|
// Seen in Don't Starve Giant Edition and Teslagrad
|
||||||
// also used by DS Virtual Console (Super Mario 64 DS)
|
// also used by DS Virtual Console (Super Mario 64 DS)
|
||||||
PPC_OPC_TEMPL3_XO();
|
PPC_OPC_TEMPL3_XO();
|
||||||
hCPU->gpr[rD] = ~hCPU->gpr[rA] + hCPU->gpr[rB] + 1;
|
uint32 result = ~hCPU->gpr[rA] + hCPU->gpr[rB] + 1;
|
||||||
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~hCPU->gpr[rA], hCPU->gpr[rB], hCPU->gpr[rD]));
|
PPCInterpreter_setXerOV(hCPU, checkAdditionOverflow(~hCPU->gpr[rA], hCPU->gpr[rB], result));
|
||||||
|
hCPU->gpr[rD] = result;
|
||||||
if (opHasRC())
|
if (opHasRC())
|
||||||
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
|
ppc_update_cr0(hCPU, hCPU->gpr[rD]);
|
||||||
PPCInterpreter_nextInstruction(hCPU);
|
PPCInterpreter_nextInstruction(hCPU);
|
||||||
|
@ -90,7 +90,7 @@ uint8* PPCInterpreterGetStackPointer()
|
|||||||
return memory_getPointerFromVirtualOffset(PPCInterpreter_getCurrentInstance()->gpr[1]);
|
return memory_getPointerFromVirtualOffset(PPCInterpreter_getCurrentInstance()->gpr[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset)
|
uint8* PPCInterpreter_PushAndReturnStackPointer(sint32 offset)
|
||||||
{
|
{
|
||||||
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
|
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
|
||||||
uint8* result = memory_getPointerFromVirtualOffset(hCPU->gpr[1] - offset);
|
uint8* result = memory_getPointerFromVirtualOffset(hCPU->gpr[1] - offset);
|
||||||
|
@ -5,8 +5,28 @@ struct PPCCoreCallbackData_t
|
|||||||
{
|
{
|
||||||
sint32 gprCount = 0;
|
sint32 gprCount = 0;
|
||||||
sint32 floatCount = 0;
|
sint32 floatCount = 0;
|
||||||
|
sint32 stackCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void _PPCCoreCallback_writeGPRArg(PPCCoreCallbackData_t& data, PPCInterpreter_t* hCPU, uint32 value)
|
||||||
|
{
|
||||||
|
if (data.gprCount < 8)
|
||||||
|
{
|
||||||
|
hCPU->gpr[3 + data.gprCount] = value;
|
||||||
|
data.gprCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 stackOffset = 8 + data.stackCount * 4;
|
||||||
|
|
||||||
|
// PPCCore_executeCallbackInternal does -16*4 to save the current stack area
|
||||||
|
stackOffset -= 16 * 4;
|
||||||
|
|
||||||
|
memory_writeU32(hCPU->gpr[1] + stackOffset, value);
|
||||||
|
data.stackCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// callback functions
|
// callback functions
|
||||||
inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data)
|
inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data)
|
||||||
{
|
{
|
||||||
@ -16,23 +36,21 @@ inline uint32 PPCCoreCallback(MPTR function, const PPCCoreCallbackData_t& data)
|
|||||||
template <typename T, typename... TArgs>
|
template <typename T, typename... TArgs>
|
||||||
uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg, TArgs... args)
|
uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg, TArgs... args)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(data.gprCount <= 8);
|
// TODO float arguments on stack
|
||||||
cemu_assert_debug(data.floatCount <= 8);
|
cemu_assert_debug(data.floatCount < 8);
|
||||||
|
|
||||||
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
|
PPCInterpreter_t* hCPU = PPCInterpreter_getCurrentInstance();
|
||||||
if constexpr (std::is_pointer_v<T>)
|
if constexpr (std::is_pointer_v<T>)
|
||||||
{
|
{
|
||||||
hCPU->gpr[3 + data.gprCount] = MEMPTR(currentArg).GetMPTR();
|
_PPCCoreCallback_writeGPRArg(data, hCPU, MEMPTR(currentArg).GetMPTR());
|
||||||
data.gprCount++;
|
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_base_of_v<MEMPTRBase, std::remove_reference_t<T>>)
|
else if constexpr (std::is_base_of_v<MEMPTRBase, std::remove_reference_t<T>>)
|
||||||
{
|
{
|
||||||
hCPU->gpr[3 + data.gprCount] = currentArg.GetMPTR();
|
_PPCCoreCallback_writeGPRArg(data, hCPU, currentArg.GetMPTR());
|
||||||
data.gprCount++;
|
|
||||||
}
|
}
|
||||||
else if constexpr (std::is_reference_v<T>)
|
else if constexpr (std::is_reference_v<T>)
|
||||||
{
|
{
|
||||||
hCPU->gpr[3 + data.gprCount] = MEMPTR(¤tArg).GetMPTR();
|
_PPCCoreCallback_writeGPRArg(data, hCPU, MEMPTR(¤tArg).GetMPTR());
|
||||||
data.gprCount++;
|
|
||||||
}
|
}
|
||||||
else if constexpr(std::is_enum_v<T>)
|
else if constexpr(std::is_enum_v<T>)
|
||||||
{
|
{
|
||||||
@ -53,8 +71,7 @@ uint32 PPCCoreCallback(MPTR function, PPCCoreCallbackData_t& data, T currentArg,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hCPU->gpr[3 + data.gprCount] = (uint32)currentArg;
|
_PPCCoreCallback_writeGPRArg(data, hCPU, (uint32)currentArg);
|
||||||
data.gprCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return PPCCoreCallback(function, data, args...);
|
return PPCCoreCallback(function, data, args...);
|
||||||
|
@ -213,7 +213,7 @@ void PPCTimer_start();
|
|||||||
// core info and control
|
// core info and control
|
||||||
extern uint32 ppcThreadQuantum;
|
extern uint32 ppcThreadQuantum;
|
||||||
|
|
||||||
uint8* PPCInterpreterGetAndModifyStackPointer(sint32 offset);
|
uint8* PPCInterpreter_PushAndReturnStackPointer(sint32 offset);
|
||||||
uint8* PPCInterpreterGetStackPointer();
|
uint8* PPCInterpreterGetStackPointer();
|
||||||
void PPCInterpreterModifyStackPointer(sint32 offset);
|
void PPCInterpreterModifyStackPointer(sint32 offset);
|
||||||
|
|
||||||
|
@ -524,7 +524,7 @@ void LatteSHRC_UpdateGSBaseHash(uint8* geometryShaderPtr, uint32 geometryShaderS
|
|||||||
// update hash from geometry shader data
|
// update hash from geometry shader data
|
||||||
uint64 gsHash1 = 0;
|
uint64 gsHash1 = 0;
|
||||||
uint64 gsHash2 = 0;
|
uint64 gsHash2 = 0;
|
||||||
_calculateShaderProgramHash((uint32*)geometryShaderPtr, geometryShaderSize, &hashCacheVS, &gsHash1, &gsHash2);
|
_calculateShaderProgramHash((uint32*)geometryShaderPtr, geometryShaderSize, &hashCacheGS, &gsHash1, &gsHash2);
|
||||||
// get geometry shader
|
// get geometry shader
|
||||||
uint64 gsHash = gsHash1 + gsHash2;
|
uint64 gsHash = gsHash1 + gsHash2;
|
||||||
gsHash += (uint64)_activeVertexShader->ringParameterCount;
|
gsHash += (uint64)_activeVertexShader->ringParameterCount;
|
||||||
|
@ -235,6 +235,9 @@ void LatteTexture_InitSliceAndMipInfo(LatteTexture* texture)
|
|||||||
// if this function returns false, textures will not be synchronized even if their data overlaps
|
// if this function returns false, textures will not be synchronized even if their data overlaps
|
||||||
bool LatteTexture_IsFormatViewCompatible(Latte::E_GX2SURFFMT formatA, Latte::E_GX2SURFFMT formatB)
|
bool LatteTexture_IsFormatViewCompatible(Latte::E_GX2SURFFMT formatA, Latte::E_GX2SURFFMT formatB)
|
||||||
{
|
{
|
||||||
|
if(formatA == formatB)
|
||||||
|
return true; // if the format is identical then compatibility must be guaranteed (otherwise we can't create the necessary default view of a texture)
|
||||||
|
|
||||||
// todo - find a better way to handle this
|
// todo - find a better way to handle this
|
||||||
for (sint32 swap = 0; swap < 2; swap++)
|
for (sint32 swap = 0; swap < 2; swap++)
|
||||||
{
|
{
|
||||||
|
@ -241,6 +241,16 @@ void LatteDecompiler_emitAttributeDecodeGLSL(LatteDecompilerShader* shaderContex
|
|||||||
src->add("attrDecoder.z = floatBitsToUint(max(float(int(attrDecoder.z))/32767.0,-1.0));" _CRLF);
|
src->add("attrDecoder.z = floatBitsToUint(max(float(int(attrDecoder.z))/32767.0,-1.0));" _CRLF);
|
||||||
src->add("attrDecoder.w = floatBitsToUint(max(float(int(attrDecoder.w))/32767.0,-1.0));" _CRLF);
|
src->add("attrDecoder.w = floatBitsToUint(max(float(int(attrDecoder.w))/32767.0,-1.0));" _CRLF);
|
||||||
}
|
}
|
||||||
|
else if( attrib->format == FMT_16_16_16_16 && attrib->nfa == 2 && attrib->isSigned == 1 )
|
||||||
|
{
|
||||||
|
// seen in Rabbids Land
|
||||||
|
_readLittleEndianAttributeU16x4(shaderContext, src, attributeInputIndex);
|
||||||
|
src->add("if( (attrDecoder.x&0x8000) != 0 ) attrDecoder.x |= 0xFFFF0000;" _CRLF);
|
||||||
|
src->add("if( (attrDecoder.y&0x8000) != 0 ) attrDecoder.y |= 0xFFFF0000;" _CRLF);
|
||||||
|
src->add("if( (attrDecoder.z&0x8000) != 0 ) attrDecoder.z |= 0xFFFF0000;" _CRLF);
|
||||||
|
src->add("if( (attrDecoder.w&0x8000) != 0 ) attrDecoder.w |= 0xFFFF0000;" _CRLF);
|
||||||
|
src->add("attrDecoder.xyzw = floatBitsToUint(vec4(ivec4(attrDecoder)));" _CRLF);
|
||||||
|
}
|
||||||
else if (attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2)
|
else if (attrib->format == FMT_16_16_16_16_FLOAT && attrib->nfa == 2)
|
||||||
{
|
{
|
||||||
// seen in Giana Sisters: Twisted Dreams
|
// seen in Giana Sisters: Twisted Dreams
|
||||||
@ -496,3 +506,5 @@ void LatteDecompiler_emitAttributeDecodeGLSL(LatteDecompilerShader* shaderContex
|
|||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,16 +23,13 @@ bool RendererShaderGL::loadBinary()
|
|||||||
cemu_assert_debug(m_baseHash != 0);
|
cemu_assert_debug(m_baseHash != 0);
|
||||||
uint64 h1, h2;
|
uint64 h1, h2;
|
||||||
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
|
GenerateShaderPrecompiledCacheFilename(m_type, m_baseHash, m_auxHash, h1, h2);
|
||||||
sint32 fileSize = 0;
|
|
||||||
std::vector<uint8> cacheFileData;
|
std::vector<uint8> cacheFileData;
|
||||||
if (!s_programBinaryCache->GetFile({h1, h2 }, cacheFileData))
|
if (!s_programBinaryCache->GetFile({h1, h2 }, cacheFileData))
|
||||||
return false;
|
return false;
|
||||||
if (fileSize < sizeof(uint32))
|
if (cacheFileData.size() <= sizeof(uint32))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
uint32 shaderBinFormat = *(uint32*)(cacheFileData.data() + 0);
|
uint32 shaderBinFormat = *(uint32*)(cacheFileData.data());
|
||||||
|
|
||||||
m_program = glCreateProgram();
|
m_program = glCreateProgram();
|
||||||
glProgramBinary(m_program, shaderBinFormat, cacheFileData.data()+4, cacheFileData.size()-4);
|
glProgramBinary(m_program, shaderBinFormat, cacheFileData.data()+4, cacheFileData.size()-4);
|
||||||
|
@ -12,9 +12,9 @@ uint32 RendererShader::GeneratePrecompiledCacheId()
|
|||||||
v += (uint32)(*s);
|
v += (uint32)(*s);
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
v += (EMULATOR_VERSION_LEAD * 1000000u);
|
v += (EMULATOR_VERSION_MAJOR * 1000000u);
|
||||||
v += (EMULATOR_VERSION_MAJOR * 10000u);
|
v += (EMULATOR_VERSION_MINOR * 10000u);
|
||||||
v += (EMULATOR_VERSION_MINOR * 100u);
|
v += (EMULATOR_VERSION_PATCH * 100u);
|
||||||
|
|
||||||
// settings that can influence shaders
|
// settings that can influence shaders
|
||||||
v += (uint32)g_current_game_profile->GetAccurateShaderMul() * 133;
|
v += (uint32)g_current_game_profile->GetAccurateShaderMul() * 133;
|
||||||
|
@ -146,8 +146,17 @@ void SwapchainInfoVk::Create()
|
|||||||
UnrecoverableError("Failed to create semaphore for swapchain acquire");
|
UnrecoverableError("Failed to create semaphore for swapchain acquire");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceInfo = {};
|
||||||
|
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
result = vkCreateFence(m_logicalDevice, &fenceInfo, nullptr, &m_imageAvailableFence);
|
||||||
|
if (result != VK_SUCCESS)
|
||||||
|
UnrecoverableError("Failed to create fence for swapchain");
|
||||||
|
|
||||||
m_acquireIndex = 0;
|
m_acquireIndex = 0;
|
||||||
hasDefinedSwapchainImage = false;
|
hasDefinedSwapchainImage = false;
|
||||||
|
|
||||||
|
m_queueDepth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapchainInfoVk::Cleanup()
|
void SwapchainInfoVk::Cleanup()
|
||||||
@ -177,6 +186,12 @@ void SwapchainInfoVk::Cleanup()
|
|||||||
m_swapchainFramebuffers.clear();
|
m_swapchainFramebuffers.clear();
|
||||||
|
|
||||||
|
|
||||||
|
if (m_imageAvailableFence)
|
||||||
|
{
|
||||||
|
WaitAvailableFence();
|
||||||
|
vkDestroyFence(m_logicalDevice, m_imageAvailableFence, nullptr);
|
||||||
|
m_imageAvailableFence = nullptr;
|
||||||
|
}
|
||||||
if (m_swapchain)
|
if (m_swapchain)
|
||||||
{
|
{
|
||||||
vkDestroySwapchainKHR(m_logicalDevice, m_swapchain, nullptr);
|
vkDestroySwapchainKHR(m_logicalDevice, m_swapchain, nullptr);
|
||||||
@ -189,6 +204,18 @@ bool SwapchainInfoVk::IsValid() const
|
|||||||
return m_swapchain && !m_acquireSemaphores.empty();
|
return m_swapchain && !m_acquireSemaphores.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SwapchainInfoVk::WaitAvailableFence()
|
||||||
|
{
|
||||||
|
if(m_awaitableFence != VK_NULL_HANDLE)
|
||||||
|
vkWaitForFences(m_logicalDevice, 1, &m_awaitableFence, VK_TRUE, UINT64_MAX);
|
||||||
|
m_awaitableFence = VK_NULL_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapchainInfoVk::ResetAvailableFence() const
|
||||||
|
{
|
||||||
|
vkResetFences(m_logicalDevice, 1, &m_imageAvailableFence);
|
||||||
|
}
|
||||||
|
|
||||||
VkSemaphore SwapchainInfoVk::ConsumeAcquireSemaphore()
|
VkSemaphore SwapchainInfoVk::ConsumeAcquireSemaphore()
|
||||||
{
|
{
|
||||||
VkSemaphore ret = m_currentSemaphore;
|
VkSemaphore ret = m_currentSemaphore;
|
||||||
@ -198,8 +225,10 @@ VkSemaphore SwapchainInfoVk::ConsumeAcquireSemaphore()
|
|||||||
|
|
||||||
bool SwapchainInfoVk::AcquireImage()
|
bool SwapchainInfoVk::AcquireImage()
|
||||||
{
|
{
|
||||||
|
ResetAvailableFence();
|
||||||
|
|
||||||
VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
|
VkSemaphore acquireSemaphore = m_acquireSemaphores[m_acquireIndex];
|
||||||
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, m_swapchain, 1'000'000'000, acquireSemaphore, nullptr, &swapchainImageIndex);
|
VkResult result = vkAcquireNextImageKHR(m_logicalDevice, m_swapchain, 1'000'000'000, acquireSemaphore, m_imageAvailableFence, &swapchainImageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||||
m_shouldRecreate = true;
|
m_shouldRecreate = true;
|
||||||
if (result == VK_TIMEOUT)
|
if (result == VK_TIMEOUT)
|
||||||
@ -216,6 +245,7 @@ bool SwapchainInfoVk::AcquireImage()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_currentSemaphore = acquireSemaphore;
|
m_currentSemaphore = acquireSemaphore;
|
||||||
|
m_awaitableFence = m_imageAvailableFence;
|
||||||
m_acquireIndex = (m_acquireIndex + 1) % m_swapchainImages.size();
|
m_acquireIndex = (m_acquireIndex + 1) % m_swapchainImages.size();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -319,6 +349,7 @@ VkExtent2D SwapchainInfoVk::ChooseSwapExtent(const VkSurfaceCapabilitiesKHR& cap
|
|||||||
|
|
||||||
VkPresentModeKHR SwapchainInfoVk::ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes)
|
VkPresentModeKHR SwapchainInfoVk::ChoosePresentMode(const std::vector<VkPresentModeKHR>& modes)
|
||||||
{
|
{
|
||||||
|
m_maxQueued = 0;
|
||||||
const auto vsyncState = (VSync)GetConfig().vsync.GetValue();
|
const auto vsyncState = (VSync)GetConfig().vsync.GetValue();
|
||||||
if (vsyncState == VSync::MAILBOX)
|
if (vsyncState == VSync::MAILBOX)
|
||||||
{
|
{
|
||||||
@ -345,6 +376,7 @@ VkPresentModeKHR SwapchainInfoVk::ChoosePresentMode(const std::vector<VkPresentM
|
|||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_maxQueued = 1;
|
||||||
return VK_PRESENT_MODE_FIFO_KHR;
|
return VK_PRESENT_MODE_FIFO_KHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,9 @@ struct SwapchainInfoVk
|
|||||||
|
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
|
void WaitAvailableFence();
|
||||||
|
void ResetAvailableFence() const;
|
||||||
|
|
||||||
bool AcquireImage();
|
bool AcquireImage();
|
||||||
// retrieve semaphore of last acquire for submitting a wait operation
|
// retrieve semaphore of last acquire for submitting a wait operation
|
||||||
// only one wait operation must be submitted per acquire (which submits a single signal operation)
|
// only one wait operation must be submitted per acquire (which submits a single signal operation)
|
||||||
@ -68,6 +71,9 @@ struct SwapchainInfoVk
|
|||||||
VkSwapchainKHR m_swapchain{};
|
VkSwapchainKHR m_swapchain{};
|
||||||
Vector2i m_desiredExtent{};
|
Vector2i m_desiredExtent{};
|
||||||
uint32 swapchainImageIndex = (uint32)-1;
|
uint32 swapchainImageIndex = (uint32)-1;
|
||||||
|
uint64 m_presentId = 1;
|
||||||
|
uint64 m_queueDepth = 0; // number of frames with pending presentation requests
|
||||||
|
uint64 m_maxQueued = 0; // the maximum number of frames with presentation requests.
|
||||||
|
|
||||||
|
|
||||||
// swapchain image ringbuffer (indexed by swapchainImageIndex)
|
// swapchain image ringbuffer (indexed by swapchainImageIndex)
|
||||||
@ -81,6 +87,8 @@ struct SwapchainInfoVk
|
|||||||
private:
|
private:
|
||||||
uint32 m_acquireIndex = 0;
|
uint32 m_acquireIndex = 0;
|
||||||
std::vector<VkSemaphore> m_acquireSemaphores; // indexed by m_acquireIndex
|
std::vector<VkSemaphore> m_acquireSemaphores; // indexed by m_acquireIndex
|
||||||
|
VkFence m_imageAvailableFence{};
|
||||||
|
VkFence m_awaitableFence = VK_NULL_HANDLE;
|
||||||
VkSemaphore m_currentSemaphore = VK_NULL_HANDLE;
|
VkSemaphore m_currentSemaphore = VK_NULL_HANDLE;
|
||||||
|
|
||||||
std::array<uint32, 2> m_swapchainQueueFamilyIndices;
|
std::array<uint32, 2> m_swapchainQueueFamilyIndices;
|
||||||
|
@ -188,6 +188,9 @@ VKFUNC_DEVICE(vkCmdPipelineBarrier2KHR);
|
|||||||
VKFUNC_DEVICE(vkCmdBeginRenderingKHR);
|
VKFUNC_DEVICE(vkCmdBeginRenderingKHR);
|
||||||
VKFUNC_DEVICE(vkCmdEndRenderingKHR);
|
VKFUNC_DEVICE(vkCmdEndRenderingKHR);
|
||||||
|
|
||||||
|
// khr_present_wait
|
||||||
|
VKFUNC_DEVICE(vkWaitForPresentKHR);
|
||||||
|
|
||||||
// transform feedback extension
|
// transform feedback extension
|
||||||
VKFUNC_DEVICE(vkCmdBindTransformFeedbackBuffersEXT);
|
VKFUNC_DEVICE(vkCmdBindTransformFeedbackBuffersEXT);
|
||||||
VKFUNC_DEVICE(vkCmdBeginTransformFeedbackEXT);
|
VKFUNC_DEVICE(vkCmdBeginTransformFeedbackEXT);
|
||||||
|
@ -826,7 +826,7 @@ void PipelineCompiler::InitDepthStencilState()
|
|||||||
|
|
||||||
depthStencilState.front.reference = stencilRefFront;
|
depthStencilState.front.reference = stencilRefFront;
|
||||||
depthStencilState.front.compareMask = stencilCompareMaskFront;
|
depthStencilState.front.compareMask = stencilCompareMaskFront;
|
||||||
depthStencilState.front.writeMask = stencilWriteMaskBack;
|
depthStencilState.front.writeMask = stencilWriteMaskFront;
|
||||||
depthStencilState.front.compareOp = vkDepthCompareTable[(size_t)frontStencilFunc];
|
depthStencilState.front.compareOp = vkDepthCompareTable[(size_t)frontStencilFunc];
|
||||||
depthStencilState.front.depthFailOp = stencilOpTable[(size_t)frontStencilZFail];
|
depthStencilState.front.depthFailOp = stencilOpTable[(size_t)frontStencilZFail];
|
||||||
depthStencilState.front.failOp = stencilOpTable[(size_t)frontStencilFail];
|
depthStencilState.front.failOp = stencilOpTable[(size_t)frontStencilFail];
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "Cafe/HW/Latte/Core/LatteBufferCache.h"
|
#include "Cafe/HW/Latte/Core/LatteBufferCache.h"
|
||||||
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
#include "Cafe/HW/Latte/Core/LattePerformanceMonitor.h"
|
||||||
|
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||||
|
|
||||||
#include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h"
|
#include "Cafe/HW/Latte/LegacyShaderDecompiler/LatteDecompiler.h"
|
||||||
|
|
||||||
@ -29,6 +30,7 @@
|
|||||||
#include <glslang/Public/ShaderLang.h>
|
#include <glslang/Public/ShaderLang.h>
|
||||||
|
|
||||||
#include <wx/msgdlg.h>
|
#include <wx/msgdlg.h>
|
||||||
|
#include <wx/intl.h> // for localization
|
||||||
|
|
||||||
#ifndef VK_API_VERSION_MAJOR
|
#ifndef VK_API_VERSION_MAJOR
|
||||||
#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU)
|
#define VK_API_VERSION_MAJOR(version) (((uint32_t)(version) >> 22) & 0x7FU)
|
||||||
@ -45,7 +47,9 @@ const std::vector<const char*> kOptionalDeviceExtensions =
|
|||||||
VK_EXT_FILTER_CUBIC_EXTENSION_NAME, // not supported by any device yet
|
VK_EXT_FILTER_CUBIC_EXTENSION_NAME, // not supported by any device yet
|
||||||
VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME,
|
VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME,
|
||||||
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
|
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
|
||||||
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME
|
VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME,
|
||||||
|
VK_KHR_PRESENT_WAIT_EXTENSION_NAME,
|
||||||
|
VK_KHR_PRESENT_ID_EXTENSION_NAME
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<const char*> kRequiredDeviceExtensions =
|
const std::vector<const char*> kRequiredDeviceExtensions =
|
||||||
@ -123,7 +127,7 @@ std::vector<VulkanRenderer::DeviceInfo> VulkanRenderer::GetDevices()
|
|||||||
VkApplicationInfo app_info{};
|
VkApplicationInfo app_info{};
|
||||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
app_info.pApplicationName = EMULATOR_NAME;
|
app_info.pApplicationName = EMULATOR_NAME;
|
||||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR);
|
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH);
|
||||||
app_info.pEngineName = EMULATOR_NAME;
|
app_info.pEngineName = EMULATOR_NAME;
|
||||||
app_info.engineVersion = app_info.applicationVersion;
|
app_info.engineVersion = app_info.applicationVersion;
|
||||||
app_info.apiVersion = apiVersion;
|
app_info.apiVersion = apiVersion;
|
||||||
@ -250,12 +254,24 @@ void VulkanRenderer::GetDeviceFeatures()
|
|||||||
pcc.pNext = prevStruct;
|
pcc.pNext = prevStruct;
|
||||||
prevStruct = &pcc;
|
prevStruct = &pcc;
|
||||||
|
|
||||||
|
VkPhysicalDevicePresentIdFeaturesKHR pidf{};
|
||||||
|
pidf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR;
|
||||||
|
pidf.pNext = prevStruct;
|
||||||
|
prevStruct = &pidf;
|
||||||
|
|
||||||
|
VkPhysicalDevicePresentWaitFeaturesKHR pwf{};
|
||||||
|
pwf.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR;
|
||||||
|
pwf.pNext = prevStruct;
|
||||||
|
prevStruct = &pwf;
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
|
VkPhysicalDeviceFeatures2 physicalDeviceFeatures2{};
|
||||||
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
physicalDeviceFeatures2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
|
||||||
physicalDeviceFeatures2.pNext = prevStruct;
|
physicalDeviceFeatures2.pNext = prevStruct;
|
||||||
|
|
||||||
vkGetPhysicalDeviceFeatures2(m_physicalDevice, &physicalDeviceFeatures2);
|
vkGetPhysicalDeviceFeatures2(m_physicalDevice, &physicalDeviceFeatures2);
|
||||||
|
|
||||||
|
cemuLog_log(LogType::Force, "Vulkan: present_wait extension: {}", (pwf.presentWait && pidf.presentId) ? "supported" : "unsupported");
|
||||||
|
|
||||||
/* Get Vulkan device properties and limits */
|
/* Get Vulkan device properties and limits */
|
||||||
VkPhysicalDeviceFloatControlsPropertiesKHR pfcp{};
|
VkPhysicalDeviceFloatControlsPropertiesKHR pfcp{};
|
||||||
prevStruct = nullptr;
|
prevStruct = nullptr;
|
||||||
@ -285,7 +301,7 @@ void VulkanRenderer::GetDeviceFeatures()
|
|||||||
cemuLog_log(LogType::Force, "VK_EXT_pipeline_creation_cache_control not supported. Cannot use asynchronous shader and pipeline compilation");
|
cemuLog_log(LogType::Force, "VK_EXT_pipeline_creation_cache_control not supported. Cannot use asynchronous shader and pipeline compilation");
|
||||||
// if async shader compilation is enabled show warning message
|
// if async shader compilation is enabled show warning message
|
||||||
if (GetConfig().async_compile)
|
if (GetConfig().async_compile)
|
||||||
wxMessageBox(_("The currently installed graphics driver does not support the Vulkan extension necessary for asynchronous shader compilation. Asynchronous compilation cannot be used.\n \nRequired extension: VK_EXT_pipeline_creation_cache_control\n\nInstalling the latest graphics driver may solve this error."), _("Information"), wxOK | wxCENTRE);
|
LatteOverlay_pushNotification(_("Async shader compile is enabled but not supported by the graphics driver\nCemu will use synchronous compilation which can cause additional stutter").utf8_string(), 10000);
|
||||||
}
|
}
|
||||||
if (!m_featureControl.deviceExtensions.custom_border_color_without_format)
|
if (!m_featureControl.deviceExtensions.custom_border_color_without_format)
|
||||||
{
|
{
|
||||||
@ -337,7 +353,7 @@ VulkanRenderer::VulkanRenderer()
|
|||||||
VkApplicationInfo app_info{};
|
VkApplicationInfo app_info{};
|
||||||
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
||||||
app_info.pApplicationName = EMULATOR_NAME;
|
app_info.pApplicationName = EMULATOR_NAME;
|
||||||
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_LEAD, EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR);
|
app_info.applicationVersion = VK_MAKE_VERSION(EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH);
|
||||||
app_info.pEngineName = EMULATOR_NAME;
|
app_info.pEngineName = EMULATOR_NAME;
|
||||||
app_info.engineVersion = app_info.applicationVersion;
|
app_info.engineVersion = app_info.applicationVersion;
|
||||||
app_info.apiVersion = apiVersion;
|
app_info.apiVersion = apiVersion;
|
||||||
@ -488,6 +504,24 @@ VulkanRenderer::VulkanRenderer()
|
|||||||
customBorderColorFeature.customBorderColors = VK_TRUE;
|
customBorderColorFeature.customBorderColors = VK_TRUE;
|
||||||
customBorderColorFeature.customBorderColorWithoutFormat = VK_TRUE;
|
customBorderColorFeature.customBorderColorWithoutFormat = VK_TRUE;
|
||||||
}
|
}
|
||||||
|
// enable VK_KHR_present_id
|
||||||
|
VkPhysicalDevicePresentIdFeaturesKHR presentIdFeature{};
|
||||||
|
if(m_featureControl.deviceExtensions.present_wait)
|
||||||
|
{
|
||||||
|
presentIdFeature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR;
|
||||||
|
presentIdFeature.pNext = deviceExtensionFeatures;
|
||||||
|
deviceExtensionFeatures = &presentIdFeature;
|
||||||
|
presentIdFeature.presentId = VK_TRUE;
|
||||||
|
}
|
||||||
|
// enable VK_KHR_present_wait
|
||||||
|
VkPhysicalDevicePresentWaitFeaturesKHR presentWaitFeature{};
|
||||||
|
if(m_featureControl.deviceExtensions.present_wait)
|
||||||
|
{
|
||||||
|
presentWaitFeature.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR;
|
||||||
|
presentWaitFeature.pNext = deviceExtensionFeatures;
|
||||||
|
deviceExtensionFeatures = &presentWaitFeature;
|
||||||
|
presentWaitFeature.presentWait = VK_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const char*> used_extensions;
|
std::vector<const char*> used_extensions;
|
||||||
VkDeviceCreateInfo createInfo = CreateDeviceCreateInfo(queueCreateInfos, deviceFeatures, deviceExtensionFeatures, used_extensions);
|
VkDeviceCreateInfo createInfo = CreateDeviceCreateInfo(queueCreateInfos, deviceFeatures, deviceExtensionFeatures, used_extensions);
|
||||||
@ -1045,6 +1079,10 @@ VkDeviceCreateInfo VulkanRenderer::CreateDeviceCreateInfo(const std::vector<VkDe
|
|||||||
used_extensions.emplace_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
used_extensions.emplace_back(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
||||||
if (m_featureControl.deviceExtensions.shader_float_controls)
|
if (m_featureControl.deviceExtensions.shader_float_controls)
|
||||||
used_extensions.emplace_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
used_extensions.emplace_back(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
||||||
|
if (m_featureControl.deviceExtensions.present_wait)
|
||||||
|
used_extensions.emplace_back(VK_KHR_PRESENT_ID_EXTENSION_NAME);
|
||||||
|
if (m_featureControl.deviceExtensions.present_wait)
|
||||||
|
used_extensions.emplace_back(VK_KHR_PRESENT_WAIT_EXTENSION_NAME);
|
||||||
|
|
||||||
VkDeviceCreateInfo createInfo{};
|
VkDeviceCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
@ -1142,6 +1180,7 @@ bool VulkanRenderer::CheckDeviceExtensionSupport(const VkPhysicalDevice device,
|
|||||||
info.deviceExtensions.shader_float_controls = isExtensionAvailable(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
info.deviceExtensions.shader_float_controls = isExtensionAvailable(VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME);
|
||||||
info.deviceExtensions.dynamic_rendering = false; // isExtensionAvailable(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
info.deviceExtensions.dynamic_rendering = false; // isExtensionAvailable(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
|
||||||
// dynamic rendering doesn't provide any benefits for us right now. Driver implementations are very unoptimized as of Feb 2022
|
// dynamic rendering doesn't provide any benefits for us right now. Driver implementations are very unoptimized as of Feb 2022
|
||||||
|
info.deviceExtensions.present_wait = isExtensionAvailable(VK_KHR_PRESENT_WAIT_EXTENSION_NAME) && isExtensionAvailable(VK_KHR_PRESENT_ID_EXTENSION_NAME);
|
||||||
|
|
||||||
// check for framedebuggers
|
// check for framedebuggers
|
||||||
info.debugMarkersSupported = false;
|
info.debugMarkersSupported = false;
|
||||||
@ -2198,6 +2237,8 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
formatInfoOut->vkImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
formatInfoOut->vkImageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||||
|
if(format == (Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT | Latte::E_GX2SURFFMT::FMT_BIT_SRGB)) // Seen in Sonic Transformed level Starry Speedway. SRGB should just be ignored for native float formats?
|
||||||
|
format = Latte::E_GX2SURFFMT::R16_G16_B16_A16_FLOAT;
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
// RGBA formats
|
// RGBA formats
|
||||||
@ -2439,6 +2480,11 @@ void VulkanRenderer::GetTextureFormatInfoVK(Latte::E_GX2SURFFMT format, bool isD
|
|||||||
// used by Color Splash and Resident Evil
|
// used by Color Splash and Resident Evil
|
||||||
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UINT; // todo - should we use ABGR format?
|
formatInfoOut->vkImageFormat = VK_FORMAT_R8G8B8A8_UINT; // todo - should we use ABGR format?
|
||||||
formatInfoOut->decoder = TextureDecoder_X24_G8_UINT::getInstance(); // todo - verify
|
formatInfoOut->decoder = TextureDecoder_X24_G8_UINT::getInstance(); // todo - verify
|
||||||
|
case Latte::E_GX2SURFFMT::R32_X8_FLOAT:
|
||||||
|
// seen in Disney Infinity 3.0
|
||||||
|
formatInfoOut->vkImageFormat = VK_FORMAT_R32_SFLOAT;
|
||||||
|
formatInfoOut->decoder = TextureDecoder_NullData64::getInstance();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
cemuLog_log(LogType::Force, "Unsupported color texture format {:04x}", (uint32)format);
|
cemuLog_log(LogType::Force, "Unsupported color texture format {:04x}", (uint32)format);
|
||||||
cemu_assert_debug(false);
|
cemu_assert_debug(false);
|
||||||
@ -2686,11 +2732,21 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
|
|||||||
ClearColorImageRaw(chainInfo.m_swapchainImages[chainInfo.swapchainImageIndex], 0, 0, clearColor, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
ClearColorImageRaw(chainInfo.m_swapchainImages[chainInfo.swapchainImageIndex], 0, 0, clearColor, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const size_t currentFrameCmdBufferID = GetCurrentCommandBufferId();
|
||||||
|
|
||||||
VkSemaphore presentSemaphore = chainInfo.m_presentSemaphores[chainInfo.swapchainImageIndex];
|
VkSemaphore presentSemaphore = chainInfo.m_presentSemaphores[chainInfo.swapchainImageIndex];
|
||||||
SubmitCommandBuffer(presentSemaphore); // submit all command and signal semaphore
|
SubmitCommandBuffer(presentSemaphore); // submit all command and signal semaphore
|
||||||
|
|
||||||
cemu_assert_debug(m_numSubmittedCmdBuffers > 0);
|
cemu_assert_debug(m_numSubmittedCmdBuffers > 0);
|
||||||
|
|
||||||
|
// wait for the previous frame to finish rendering
|
||||||
|
WaitCommandBufferFinished(m_commandBufferIDOfPrevFrame);
|
||||||
|
m_commandBufferIDOfPrevFrame = currentFrameCmdBufferID;
|
||||||
|
|
||||||
|
chainInfo.WaitAvailableFence();
|
||||||
|
|
||||||
|
VkPresentIdKHR presentId = {};
|
||||||
|
|
||||||
VkPresentInfoKHR presentInfo = {};
|
VkPresentInfoKHR presentInfo = {};
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
presentInfo.swapchainCount = 1;
|
presentInfo.swapchainCount = 1;
|
||||||
@ -2700,6 +2756,24 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
|
|||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
presentInfo.pWaitSemaphores = &presentSemaphore;
|
presentInfo.pWaitSemaphores = &presentSemaphore;
|
||||||
|
|
||||||
|
// if present_wait is available and enabled, add frame markers to present requests
|
||||||
|
// and limit the number of queued present operations
|
||||||
|
if (m_featureControl.deviceExtensions.present_wait && chainInfo.m_maxQueued > 0)
|
||||||
|
{
|
||||||
|
presentId.sType = VK_STRUCTURE_TYPE_PRESENT_ID_KHR;
|
||||||
|
presentId.swapchainCount = 1;
|
||||||
|
presentId.pPresentIds = &chainInfo.m_presentId;
|
||||||
|
|
||||||
|
presentInfo.pNext = &presentId;
|
||||||
|
|
||||||
|
if(chainInfo.m_queueDepth >= chainInfo.m_maxQueued)
|
||||||
|
{
|
||||||
|
uint64 waitFrameId = chainInfo.m_presentId - chainInfo.m_queueDepth;
|
||||||
|
vkWaitForPresentKHR(m_logicalDevice, chainInfo.m_swapchain, waitFrameId, 40'000'000);
|
||||||
|
chainInfo.m_queueDepth--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VkResult result = vkQueuePresentKHR(m_presentQueue, &presentInfo);
|
VkResult result = vkQueuePresentKHR(m_presentQueue, &presentInfo);
|
||||||
if (result < 0 && result != VK_ERROR_OUT_OF_DATE_KHR)
|
if (result < 0 && result != VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
{
|
{
|
||||||
@ -2708,6 +2782,12 @@ void VulkanRenderer::SwapBuffer(bool mainWindow)
|
|||||||
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR)
|
||||||
chainInfo.m_shouldRecreate = true;
|
chainInfo.m_shouldRecreate = true;
|
||||||
|
|
||||||
|
if(result >= 0)
|
||||||
|
{
|
||||||
|
chainInfo.m_queueDepth++;
|
||||||
|
chainInfo.m_presentId++;
|
||||||
|
}
|
||||||
|
|
||||||
chainInfo.hasDefinedSwapchainImage = false;
|
chainInfo.hasDefinedSwapchainImage = false;
|
||||||
|
|
||||||
chainInfo.swapchainImageIndex = -1;
|
chainInfo.swapchainImageIndex = -1;
|
||||||
|
@ -450,6 +450,7 @@ private:
|
|||||||
bool synchronization2 = false; // VK_KHR_synchronization2
|
bool synchronization2 = false; // VK_KHR_synchronization2
|
||||||
bool dynamic_rendering = false; // VK_KHR_dynamic_rendering
|
bool dynamic_rendering = false; // VK_KHR_dynamic_rendering
|
||||||
bool shader_float_controls = false; // VK_KHR_shader_float_controls
|
bool shader_float_controls = false; // VK_KHR_shader_float_controls
|
||||||
|
bool present_wait = false; // VK_KHR_present_wait
|
||||||
}deviceExtensions;
|
}deviceExtensions;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -635,6 +636,7 @@ private:
|
|||||||
|
|
||||||
size_t m_commandBufferIndex = 0; // current buffer being filled
|
size_t m_commandBufferIndex = 0; // current buffer being filled
|
||||||
size_t m_commandBufferSyncIndex = 0; // latest buffer that finished execution (updated on submit)
|
size_t m_commandBufferSyncIndex = 0; // latest buffer that finished execution (updated on submit)
|
||||||
|
size_t m_commandBufferIDOfPrevFrame = 0;
|
||||||
std::array<VkFence, kCommandBufferPoolSize> m_cmd_buffer_fences;
|
std::array<VkFence, kCommandBufferPoolSize> m_cmd_buffer_fences;
|
||||||
std::array<VkCommandBuffer, kCommandBufferPoolSize> m_commandBuffers;
|
std::array<VkCommandBuffer, kCommandBufferPoolSize> m_commandBuffers;
|
||||||
std::array<VkSemaphore, kCommandBufferPoolSize> m_commandBufferSemaphores;
|
std::array<VkSemaphore, kCommandBufferPoolSize> m_commandBufferSemaphores;
|
||||||
|
406
src/Cafe/IOSU/ccr_nfc/iosu_ccr_nfc.cpp
Normal file
406
src/Cafe/IOSU/ccr_nfc/iosu_ccr_nfc.cpp
Normal file
@ -0,0 +1,406 @@
|
|||||||
|
#include "iosu_ccr_nfc.h"
|
||||||
|
#include "Cafe/IOSU/kernel/iosu_kernel.h"
|
||||||
|
#include "util/crypto/aes128.h"
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
|
||||||
|
namespace iosu
|
||||||
|
{
|
||||||
|
namespace ccr_nfc
|
||||||
|
{
|
||||||
|
IOSMsgQueueId sCCRNFCMsgQueue;
|
||||||
|
SysAllocator<iosu::kernel::IOSMessage, 0x20> sCCRNFCMsgQueueMsgBuffer;
|
||||||
|
std::thread sCCRNFCThread;
|
||||||
|
|
||||||
|
constexpr uint8 sNfcKey[] = { 0xC1, 0x2B, 0x07, 0x10, 0xD7, 0x2C, 0xEB, 0x5D, 0x43, 0x49, 0xB7, 0x43, 0xE3, 0xCA, 0xD2, 0x24 };
|
||||||
|
constexpr uint8 sNfcKeyIV[] = { 0x4F, 0xD3, 0x9A, 0x6E, 0x79, 0xFC, 0xEA, 0xAD, 0x99, 0x90, 0x4D, 0xB8, 0xEE, 0x38, 0xE9, 0xDB };
|
||||||
|
|
||||||
|
constexpr uint8 sUnfixedInfosMagicBytes[] = { 0x00, 0x00, 0xDB, 0x4B, 0x9E, 0x3F, 0x45, 0x27, 0x8F, 0x39, 0x7E, 0xFF, 0x9B, 0x4F, 0xB9, 0x93 };
|
||||||
|
constexpr uint8 sLockedSecretMagicBytes[] = { 0xFD, 0xC8, 0xA0, 0x76, 0x94, 0xB8, 0x9E, 0x4C, 0x47, 0xD3, 0x7D, 0xE8, 0xCE, 0x5C, 0x74, 0xC1 };
|
||||||
|
constexpr uint8 sUnfixedInfosString[] = { 0x75, 0x6E, 0x66, 0x69, 0x78, 0x65, 0x64, 0x20, 0x69, 0x6E, 0x66, 0x6F, 0x73, 0x00, 0x00, 0x00 };
|
||||||
|
constexpr uint8 sLockedSecretString[] = { 0x6C, 0x6F, 0x63, 0x6B, 0x65, 0x64, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
|
constexpr uint8 sLockedSecretHmacKey[] = { 0x7F, 0x75, 0x2D, 0x28, 0x73, 0xA2, 0x00, 0x17, 0xFE, 0xF8, 0x5C, 0x05, 0x75, 0x90, 0x4B, 0x6D };
|
||||||
|
constexpr uint8 sUnfixedInfosHmacKey[] = { 0x1D, 0x16, 0x4B, 0x37, 0x5B, 0x72, 0xA5, 0x57, 0x28, 0xB9, 0x1D, 0x64, 0xB6, 0xA3, 0xC2, 0x05 };
|
||||||
|
|
||||||
|
uint8 sLockedSecretInternalKey[0x10];
|
||||||
|
uint8 sLockedSecretInternalNonce[0x10];
|
||||||
|
uint8 sLockedSecretInternalHmacKey[0x10];
|
||||||
|
|
||||||
|
uint8 sUnfixedInfosInternalKey[0x10];
|
||||||
|
uint8 sUnfixedInfosInternalNonce[0x10];
|
||||||
|
uint8 sUnfixedInfosInternalHmacKey[0x10];
|
||||||
|
|
||||||
|
sint32 __CCRNFCValidateCryptData(CCRNFCCryptData* data, uint32 size, bool validateOffsets)
|
||||||
|
{
|
||||||
|
if (!data)
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size != sizeof(CCRNFCCryptData))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!validateOffsets)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure all offsets are within bounds
|
||||||
|
if (data->version == 0)
|
||||||
|
{
|
||||||
|
if (data->unfixedInfosHmacOffset < 0x1C9 && data->unfixedInfosOffset < 0x1C9 &&
|
||||||
|
data->lockedSecretHmacOffset < 0x1C9 && data->lockedSecretOffset < 0x1C9 &&
|
||||||
|
data->lockedSecretSize < 0x1C9 && data->unfixedInfosSize < 0x1C9)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data->version == 2)
|
||||||
|
{
|
||||||
|
if (data->unfixedInfosHmacOffset < 0x21D && data->unfixedInfosOffset < 0x21D &&
|
||||||
|
data->lockedSecretHmacOffset < 0x21D && data->lockedSecretOffset < 0x21D &&
|
||||||
|
data->lockedSecretSize < 0x21D && data->unfixedInfosSize < 0x21D)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 CCRNFCAESCTRCrypt(const uint8* key, const void* ivNonce, const void* inData, uint32 inSize, void* outData, uint32 outSize)
|
||||||
|
{
|
||||||
|
uint8 tmpIv[0x10];
|
||||||
|
memcpy(tmpIv, ivNonce, sizeof(tmpIv));
|
||||||
|
|
||||||
|
memcpy(outData, inData, inSize);
|
||||||
|
AES128CTR_transform((uint8*)outData, outSize, (uint8*)key, tmpIv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 __CCRNFCGenerateKey(const uint8* hmacKey, uint32 hmacKeySize, const uint8* name, uint32 nameSize, const uint8* inData, uint32 inSize, uint8* outData, uint32 outSize)
|
||||||
|
{
|
||||||
|
if (nameSize != 0xe || outSize != 0x40)
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a buffer containing 2 counter bytes, the key name, and the key data
|
||||||
|
uint8 buffer[0x50];
|
||||||
|
buffer[0] = 0;
|
||||||
|
buffer[1] = 0;
|
||||||
|
memcpy(buffer + 2, name, nameSize);
|
||||||
|
memcpy(buffer + nameSize + 2, inData, inSize);
|
||||||
|
|
||||||
|
uint16 counter = 0;
|
||||||
|
while (outSize > 0)
|
||||||
|
{
|
||||||
|
// Set counter bytes and increment counter
|
||||||
|
buffer[0] = (counter >> 8) & 0xFF;
|
||||||
|
buffer[1] = counter & 0xFF;
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
uint32 dataSize = outSize;
|
||||||
|
if (!HMAC(EVP_sha256(), hmacKey, hmacKeySize, buffer, sizeof(buffer), outData, &dataSize))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
outSize -= 0x20;
|
||||||
|
outData += 0x20;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 __CCRNFCGenerateInternalKeys(const CCRNFCCryptData* in, const uint8* keyGenSalt)
|
||||||
|
{
|
||||||
|
uint8 lockedSecretBuffer[0x40] = { 0 };
|
||||||
|
uint8 unfixedInfosBuffer[0x40] = { 0 };
|
||||||
|
uint8 outBuffer[0x40] = { 0 };
|
||||||
|
|
||||||
|
// Fill the locked secret buffer
|
||||||
|
memcpy(lockedSecretBuffer, sLockedSecretMagicBytes, sizeof(sLockedSecretMagicBytes));
|
||||||
|
if (in->version == 0)
|
||||||
|
{
|
||||||
|
// For Version 0 this is the 16-byte Format Info
|
||||||
|
memcpy(lockedSecretBuffer + 0x10, in->data + in->uuidOffset, 0x10);
|
||||||
|
}
|
||||||
|
else if (in->version == 2)
|
||||||
|
{
|
||||||
|
// For Version 2 this is 2 times the 7-byte UID + 1 check byte
|
||||||
|
memcpy(lockedSecretBuffer + 0x10, in->data + in->uuidOffset, 8);
|
||||||
|
memcpy(lockedSecretBuffer + 0x18, in->data + in->uuidOffset, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
// Append key generation salt
|
||||||
|
memcpy(lockedSecretBuffer + 0x20, keyGenSalt, 0x20);
|
||||||
|
|
||||||
|
// Generate the key output
|
||||||
|
sint32 res = __CCRNFCGenerateKey(sLockedSecretHmacKey, sizeof(sLockedSecretHmacKey), sLockedSecretString, 0xe, lockedSecretBuffer, sizeof(lockedSecretBuffer), outBuffer, sizeof(outBuffer));
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the key buffer
|
||||||
|
memcpy(sLockedSecretInternalKey, outBuffer, 0x10);
|
||||||
|
memcpy(sLockedSecretInternalNonce, outBuffer + 0x10, 0x10);
|
||||||
|
memcpy(sLockedSecretInternalHmacKey, outBuffer + 0x20, 0x10);
|
||||||
|
|
||||||
|
// Fill the unfixed infos buffer
|
||||||
|
memcpy(unfixedInfosBuffer, in->data + in->seedOffset, 2);
|
||||||
|
memcpy(unfixedInfosBuffer + 2, sUnfixedInfosMagicBytes + 2, 0xe);
|
||||||
|
if (in->version == 0)
|
||||||
|
{
|
||||||
|
// For Version 0 this is the 16-byte Format Info
|
||||||
|
memcpy(unfixedInfosBuffer + 0x10, in->data + in->uuidOffset, 0x10);
|
||||||
|
}
|
||||||
|
else if (in->version == 2)
|
||||||
|
{
|
||||||
|
// For Version 2 this is 2 times the 7-byte UID + 1 check byte
|
||||||
|
memcpy(unfixedInfosBuffer + 0x10, in->data + in->uuidOffset, 8);
|
||||||
|
memcpy(unfixedInfosBuffer + 0x18, in->data + in->uuidOffset, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
// Append key generation salt
|
||||||
|
memcpy(unfixedInfosBuffer + 0x20, keyGenSalt, 0x20);
|
||||||
|
|
||||||
|
// Generate the key output
|
||||||
|
res = __CCRNFCGenerateKey(sUnfixedInfosHmacKey, sizeof(sUnfixedInfosHmacKey), sUnfixedInfosString, 0xe, unfixedInfosBuffer, sizeof(unfixedInfosBuffer), outBuffer, sizeof(outBuffer));
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unpack the key buffer
|
||||||
|
memcpy(sUnfixedInfosInternalKey, outBuffer, 0x10);
|
||||||
|
memcpy(sUnfixedInfosInternalNonce, outBuffer + 0x10, 0x10);
|
||||||
|
memcpy(sUnfixedInfosInternalHmacKey, outBuffer + 0x20, 0x10);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sint32 __CCRNFCCryptData(const CCRNFCCryptData* in, CCRNFCCryptData* out, bool decrypt)
|
||||||
|
{
|
||||||
|
// Decrypt key generation salt
|
||||||
|
uint8 keyGenSalt[0x20];
|
||||||
|
sint32 res = CCRNFCAESCTRCrypt(sNfcKey, sNfcKeyIV, in->data + in->keyGenSaltOffset, 0x20, keyGenSalt, sizeof(keyGenSalt));
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare internal keys
|
||||||
|
res = __CCRNFCGenerateInternalKeys(in, keyGenSalt);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decrypt)
|
||||||
|
{
|
||||||
|
// Only version 0 tags have an encrypted locked secret area
|
||||||
|
if (in->version == 0)
|
||||||
|
{
|
||||||
|
res = CCRNFCAESCTRCrypt(sLockedSecretInternalKey, sLockedSecretInternalNonce, in->data + in->lockedSecretOffset, in->lockedSecretSize, out->data + in->lockedSecretOffset, in->lockedSecretSize);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt unfxied infos
|
||||||
|
res = CCRNFCAESCTRCrypt(sUnfixedInfosInternalKey, sUnfixedInfosInternalNonce, in->data + in->unfixedInfosOffset, in->unfixedInfosSize, out->data + in->unfixedInfosOffset, in->unfixedInfosSize);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify HMACs
|
||||||
|
uint8 hmacBuffer[0x20];
|
||||||
|
uint32 hmacLen = sizeof(hmacBuffer);
|
||||||
|
|
||||||
|
if (!HMAC(EVP_sha256(), sLockedSecretInternalHmacKey, sizeof(sLockedSecretInternalHmacKey), out->data + in->lockedSecretHmacOffset + 0x20, (in->dataSize - in->lockedSecretHmacOffset) - 0x20, hmacBuffer, &hmacLen))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(in->data + in->lockedSecretHmacOffset, hmacBuffer, 0x20) != 0)
|
||||||
|
{
|
||||||
|
return CCR_NFC_INVALID_LOCKED_SECRET;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in->version == 0)
|
||||||
|
{
|
||||||
|
hmacLen = sizeof(hmacBuffer);
|
||||||
|
res = HMAC(EVP_sha256(), sUnfixedInfosInternalHmacKey, sizeof(sUnfixedInfosInternalHmacKey), out->data + in->unfixedInfosHmacOffset + 0x20, (in->dataSize - in->unfixedInfosHmacOffset) - 0x20, hmacBuffer, &hmacLen) ? 0 : CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hmacLen = sizeof(hmacBuffer);
|
||||||
|
res = HMAC(EVP_sha256(), sUnfixedInfosInternalHmacKey, sizeof(sUnfixedInfosInternalHmacKey), out->data + in->unfixedInfosHmacOffset + 0x21, (in->dataSize - in->unfixedInfosHmacOffset) - 0x21, hmacBuffer, &hmacLen) ? 0 : CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(in->data + in->unfixedInfosHmacOffset, hmacBuffer, 0x20) != 0)
|
||||||
|
{
|
||||||
|
return CCR_NFC_INVALID_UNFIXED_INFOS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint8 hmacBuffer[0x20];
|
||||||
|
uint32 hmacLen = sizeof(hmacBuffer);
|
||||||
|
|
||||||
|
if (!HMAC(EVP_sha256(), sLockedSecretInternalHmacKey, sizeof(sLockedSecretInternalHmacKey), out->data + in->lockedSecretHmacOffset + 0x20, (in->dataSize - in->lockedSecretHmacOffset) - 0x20, hmacBuffer, &hmacLen))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(in->data + in->lockedSecretHmacOffset, hmacBuffer, 0x20) != 0)
|
||||||
|
{
|
||||||
|
return CCR_NFC_INVALID_LOCKED_SECRET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only version 0 tags have an encrypted locked secret area
|
||||||
|
if (in->version == 0)
|
||||||
|
{
|
||||||
|
uint32 hmacLen = 0x20;
|
||||||
|
if (!HMAC(EVP_sha256(), sUnfixedInfosInternalHmacKey, sizeof(sUnfixedInfosInternalHmacKey), out->data + in->unfixedInfosHmacOffset + 0x20, (in->dataSize - in->unfixedInfosHmacOffset) - 0x20, out->data + in->unfixedInfosHmacOffset, &hmacLen))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = CCRNFCAESCTRCrypt(sLockedSecretInternalKey, sLockedSecretInternalNonce, in->data + in->lockedSecretOffset, in->lockedSecretSize, out->data + in->lockedSecretOffset, in->lockedSecretSize);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 hmacLen = 0x20;
|
||||||
|
if (!HMAC(EVP_sha256(), sUnfixedInfosInternalHmacKey, sizeof(sUnfixedInfosInternalHmacKey), out->data + in->unfixedInfosHmacOffset + 0x21, (in->dataSize - in->unfixedInfosHmacOffset) - 0x21, out->data + in->unfixedInfosHmacOffset, &hmacLen))
|
||||||
|
{
|
||||||
|
return CCR_NFC_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res = CCRNFCAESCTRCrypt(sUnfixedInfosInternalKey, sUnfixedInfosInternalNonce, in->data + in->unfixedInfosOffset, in->unfixedInfosSize, out->data + in->unfixedInfosOffset, in->unfixedInfosSize);
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CCRNFCThread()
|
||||||
|
{
|
||||||
|
iosu::kernel::IOSMessage msg;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
IOS_ERROR error = iosu::kernel::IOS_ReceiveMessage(sCCRNFCMsgQueue, &msg, 0);
|
||||||
|
cemu_assert(!IOS_ResultIsError(error));
|
||||||
|
|
||||||
|
// Check for system exit
|
||||||
|
if (msg == 0xf00dd00d)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPCCommandBody* cmd = MEMPTR<IPCCommandBody>(msg).GetPtr();
|
||||||
|
if (cmd->cmdId == IPCCommandId::IOS_OPEN)
|
||||||
|
{
|
||||||
|
iosu::kernel::IOS_ResourceReply(cmd, IOS_ERROR_OK);
|
||||||
|
}
|
||||||
|
else if (cmd->cmdId == IPCCommandId::IOS_CLOSE)
|
||||||
|
{
|
||||||
|
iosu::kernel::IOS_ResourceReply(cmd, IOS_ERROR_OK);
|
||||||
|
}
|
||||||
|
else if (cmd->cmdId == IPCCommandId::IOS_IOCTL)
|
||||||
|
{
|
||||||
|
sint32 result;
|
||||||
|
uint32 requestId = cmd->args[0];
|
||||||
|
void* ptrIn = MEMPTR<void>(cmd->args[1]);
|
||||||
|
uint32 sizeIn = cmd->args[2];
|
||||||
|
void* ptrOut = MEMPTR<void>(cmd->args[3]);
|
||||||
|
uint32 sizeOut = cmd->args[4];
|
||||||
|
|
||||||
|
if ((result = __CCRNFCValidateCryptData(static_cast<CCRNFCCryptData*>(ptrIn), sizeIn, true)) == 0 &&
|
||||||
|
(result = __CCRNFCValidateCryptData(static_cast<CCRNFCCryptData*>(ptrOut), sizeOut, false)) == 0)
|
||||||
|
{
|
||||||
|
// Initialize outData with inData
|
||||||
|
memcpy(ptrOut, ptrIn, sizeIn);
|
||||||
|
|
||||||
|
switch (requestId)
|
||||||
|
{
|
||||||
|
case 1: // encrypt
|
||||||
|
result = __CCRNFCCryptData(static_cast<CCRNFCCryptData*>(ptrIn), static_cast<CCRNFCCryptData*>(ptrOut), false);
|
||||||
|
break;
|
||||||
|
case 2: // decrypt
|
||||||
|
result = __CCRNFCCryptData(static_cast<CCRNFCCryptData*>(ptrIn), static_cast<CCRNFCCryptData*>(ptrOut), true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cemuLog_log(LogType::Force, "/dev/ccr_nfc: Unsupported IOCTL requestId");
|
||||||
|
cemu_assert_suspicious();
|
||||||
|
result = IOS_ERROR_INVALID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iosu::kernel::IOS_ResourceReply(cmd, static_cast<IOS_ERROR>(result));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cemuLog_log(LogType::Force, "/dev/ccr_nfc: Unsupported IPC cmdId");
|
||||||
|
cemu_assert_suspicious();
|
||||||
|
iosu::kernel::IOS_ResourceReply(cmd, IOS_ERROR_INVALID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class : public ::IOSUModule
|
||||||
|
{
|
||||||
|
void SystemLaunch() override
|
||||||
|
{
|
||||||
|
sCCRNFCMsgQueue = iosu::kernel::IOS_CreateMessageQueue(sCCRNFCMsgQueueMsgBuffer.GetPtr(), sCCRNFCMsgQueueMsgBuffer.GetCount());
|
||||||
|
cemu_assert(!IOS_ResultIsError(static_cast<IOS_ERROR>(sCCRNFCMsgQueue)));
|
||||||
|
|
||||||
|
IOS_ERROR error = iosu::kernel::IOS_RegisterResourceManager("/dev/ccr_nfc", sCCRNFCMsgQueue);
|
||||||
|
cemu_assert(!IOS_ResultIsError(error));
|
||||||
|
|
||||||
|
sCCRNFCThread = std::thread(CCRNFCThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SystemExit() override
|
||||||
|
{
|
||||||
|
if (sCCRNFCMsgQueue < 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
iosu::kernel::IOS_SendMessage(sCCRNFCMsgQueue, 0xf00dd00d, 0);
|
||||||
|
sCCRNFCThread.join();
|
||||||
|
|
||||||
|
iosu::kernel::IOS_DestroyMessageQueue(sCCRNFCMsgQueue);
|
||||||
|
sCCRNFCMsgQueue = -1;
|
||||||
|
}
|
||||||
|
} sIOSUModuleCCRNFC;
|
||||||
|
|
||||||
|
IOSUModule* GetModule()
|
||||||
|
{
|
||||||
|
return &sIOSUModuleCCRNFC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
src/Cafe/IOSU/ccr_nfc/iosu_ccr_nfc.h
Normal file
31
src/Cafe/IOSU/ccr_nfc/iosu_ccr_nfc.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Cafe/IOSU/iosu_types_common.h"
|
||||||
|
|
||||||
|
#define CCR_NFC_ERROR (-0x2F001E)
|
||||||
|
#define CCR_NFC_INVALID_LOCKED_SECRET (-0x2F0029)
|
||||||
|
#define CCR_NFC_INVALID_UNFIXED_INFOS (-0x2F002A)
|
||||||
|
|
||||||
|
namespace iosu
|
||||||
|
{
|
||||||
|
namespace ccr_nfc
|
||||||
|
{
|
||||||
|
struct CCRNFCCryptData
|
||||||
|
{
|
||||||
|
uint32 version;
|
||||||
|
uint32 dataSize;
|
||||||
|
uint32 seedOffset;
|
||||||
|
uint32 keyGenSaltOffset;
|
||||||
|
uint32 uuidOffset;
|
||||||
|
uint32 unfixedInfosOffset;
|
||||||
|
uint32 unfixedInfosSize;
|
||||||
|
uint32 lockedSecretOffset;
|
||||||
|
uint32 lockedSecretSize;
|
||||||
|
uint32 unfixedInfosHmacOffset;
|
||||||
|
uint32 lockedSecretHmacOffset;
|
||||||
|
uint8 data[540];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CCRNFCCryptData) == 0x248);
|
||||||
|
|
||||||
|
IOSUModule* GetModule();
|
||||||
|
}
|
||||||
|
}
|
@ -511,6 +511,8 @@ namespace iosu
|
|||||||
return CallHandler_GetBlackList(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
return CallHandler_GetBlackList(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||||
case FPD_REQUEST_ID::GetFriendListEx:
|
case FPD_REQUEST_ID::GetFriendListEx:
|
||||||
return CallHandler_GetFriendListEx(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
return CallHandler_GetFriendListEx(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||||
|
case FPD_REQUEST_ID::UpdateCommentAsync:
|
||||||
|
return CallHandler_UpdateCommentAsync(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||||
case FPD_REQUEST_ID::UpdatePreferenceAsync:
|
case FPD_REQUEST_ID::UpdatePreferenceAsync:
|
||||||
return CallHandler_UpdatePreferenceAsync(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
return CallHandler_UpdatePreferenceAsync(fpdClient, vecIn, numVecIn, vecOut, numVecOut);
|
||||||
case FPD_REQUEST_ID::AddFriendRequestByPlayRecordAsync:
|
case FPD_REQUEST_ID::AddFriendRequestByPlayRecordAsync:
|
||||||
@ -719,18 +721,23 @@ namespace iosu
|
|||||||
|
|
||||||
nnResult CallHandler_GetMyComment(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
nnResult CallHandler_GetMyComment(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||||
{
|
{
|
||||||
static constexpr uint32 MY_COMMENT_LENGTH = 0x12; // are comments utf16? Buffer length is 0x24
|
|
||||||
if(numVecIn != 0 || numVecOut != 1)
|
if(numVecIn != 0 || numVecOut != 1)
|
||||||
return FPResult_InvalidIPCParam;
|
return FPResult_InvalidIPCParam;
|
||||||
if(vecOut->size != MY_COMMENT_LENGTH*sizeof(uint16be))
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::Force, "GetMyComment: Unexpected output size");
|
|
||||||
return FPResult_InvalidIPCParam;
|
|
||||||
}
|
|
||||||
std::basic_string<uint16be> myComment;
|
std::basic_string<uint16be> myComment;
|
||||||
myComment.resize(MY_COMMENT_LENGTH);
|
if(g_fpd.nexFriendSession)
|
||||||
memcpy(vecOut->basePhys.GetPtr(), myComment.data(), MY_COMMENT_LENGTH*sizeof(uint16be));
|
{
|
||||||
return 0;
|
if(vecOut->size != MY_COMMENT_LENGTH * sizeof(uint16be))
|
||||||
|
{
|
||||||
|
cemuLog_log(LogType::Force, "GetMyComment: Unexpected output size");
|
||||||
|
return FPResult_InvalidIPCParam;
|
||||||
|
}
|
||||||
|
nexComment myNexComment;
|
||||||
|
g_fpd.nexFriendSession->getMyComment(myNexComment);
|
||||||
|
myComment = StringHelpers::FromUtf8(myNexComment.commentString);
|
||||||
|
}
|
||||||
|
myComment.insert(0, 1, '\0');
|
||||||
|
memcpy(vecOut->basePhys.GetPtr(), myComment.c_str(), MY_COMMENT_LENGTH * sizeof(uint16be));
|
||||||
|
return FPResult_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
nnResult CallHandler_GetMyPreference(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
nnResult CallHandler_GetMyPreference(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||||
@ -1143,6 +1150,36 @@ namespace iosu
|
|||||||
return FPResult_Ok;
|
return FPResult_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nnResult CallHandler_UpdateCommentAsync(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||||
|
{
|
||||||
|
std::unique_lock _l(g_fpd.mtxFriendSession);
|
||||||
|
if (numVecIn != 1 || numVecOut != 0)
|
||||||
|
return FPResult_InvalidIPCParam;
|
||||||
|
if (!g_fpd.nexFriendSession)
|
||||||
|
return FPResult_RequestFailed;
|
||||||
|
uint32 messageLength = vecIn[0].size / sizeof(uint16be);
|
||||||
|
DeclareInputPtr(newComment, uint16be, messageLength, 0);
|
||||||
|
if (messageLength == 0 || newComment[messageLength-1] != 0)
|
||||||
|
{
|
||||||
|
cemuLog_log(LogType::Force, "UpdateCommentAsync: Message must contain at least a null-termination character");
|
||||||
|
return FPResult_InvalidIPCParam;
|
||||||
|
}
|
||||||
|
IPCCommandBody* cmd = ServiceCallDelayCurrentResponse();
|
||||||
|
|
||||||
|
auto utf8_comment = StringHelpers::ToUtf8(newComment, messageLength);
|
||||||
|
nexComment temporaryComment;
|
||||||
|
temporaryComment.ukn0 = 0;
|
||||||
|
temporaryComment.commentString = utf8_comment;
|
||||||
|
temporaryComment.ukn1 = 0;
|
||||||
|
|
||||||
|
g_fpd.nexFriendSession->updateCommentAsync(temporaryComment, [cmd](NexFriends::RpcErrorCode result) {
|
||||||
|
if (result != NexFriends::ERR_NONE)
|
||||||
|
return ServiceCallAsyncRespond(cmd, FPResult_RequestFailed);
|
||||||
|
ServiceCallAsyncRespond(cmd, FPResult_Ok);
|
||||||
|
});
|
||||||
|
return FPResult_Ok;
|
||||||
|
}
|
||||||
|
|
||||||
nnResult CallHandler_UpdatePreferenceAsync(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
nnResult CallHandler_UpdatePreferenceAsync(FPDClient* fpdClient, IPCIoctlVector* vecIn, uint32 numVecIn, IPCIoctlVector* vecOut, uint32 numVecOut)
|
||||||
{
|
{
|
||||||
std::unique_lock _l(g_fpd.mtxFriendSession);
|
std::unique_lock _l(g_fpd.mtxFriendSession);
|
||||||
|
@ -212,6 +212,7 @@ namespace iosu
|
|||||||
static const int RELATIONSHIP_FRIEND = 3;
|
static const int RELATIONSHIP_FRIEND = 3;
|
||||||
|
|
||||||
static const int GAMEMODE_MAX_MESSAGE_LENGTH = 0x80; // limit includes null-terminator character, so only 0x7F actual characters can be used
|
static const int GAMEMODE_MAX_MESSAGE_LENGTH = 0x80; // limit includes null-terminator character, so only 0x7F actual characters can be used
|
||||||
|
static const int MY_COMMENT_LENGTH = 0x12;
|
||||||
|
|
||||||
enum class FPD_REQUEST_ID
|
enum class FPD_REQUEST_ID
|
||||||
{
|
{
|
||||||
@ -245,6 +246,7 @@ namespace iosu
|
|||||||
CheckSettingStatusAsync = 0x7596,
|
CheckSettingStatusAsync = 0x7596,
|
||||||
GetFriendListEx = 0x75F9,
|
GetFriendListEx = 0x75F9,
|
||||||
GetFriendRequestListEx = 0x76C1,
|
GetFriendRequestListEx = 0x76C1,
|
||||||
|
UpdateCommentAsync = 0x7726,
|
||||||
UpdatePreferenceAsync = 0x7727,
|
UpdatePreferenceAsync = 0x7727,
|
||||||
RemoveFriendAsync = 0x7789,
|
RemoveFriendAsync = 0x7789,
|
||||||
DeleteFriendFlagsAsync = 0x778A,
|
DeleteFriendFlagsAsync = 0x778A,
|
||||||
|
@ -23,3 +23,86 @@ void osLib_returnFromFunction64(PPCInterpreter_t* hCPU, uint64 returnValue64);
|
|||||||
|
|
||||||
// utility functions
|
// utility functions
|
||||||
#include "Cafe/OS/common/OSUtil.h"
|
#include "Cafe/OS/common/OSUtil.h"
|
||||||
|
|
||||||
|
// va_list
|
||||||
|
struct ppc_va_list
|
||||||
|
{
|
||||||
|
uint8be gprIndex;
|
||||||
|
uint8be fprIndex;
|
||||||
|
uint8be _padding2[2];
|
||||||
|
MEMPTR<uint8be> overflow_arg_area;
|
||||||
|
MEMPTR<uint8be> reg_save_area;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ppc_va_list) == 0xC);
|
||||||
|
|
||||||
|
struct ppc_va_list_reg_storage
|
||||||
|
{
|
||||||
|
uint32be gpr_save_area[8]; // 32 bytes, r3 to r10
|
||||||
|
float64be fpr_save_area[8]; // 64 bytes, f1 to f8
|
||||||
|
ppc_va_list vargs;
|
||||||
|
uint32be padding;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(ppc_va_list_reg_storage) == 0x70);
|
||||||
|
|
||||||
|
// Equivalent of va_start for PPC HLE functions. Must be called before any StackAllocator<> definitions
|
||||||
|
#define ppc_define_va_list(__gprIndex, __fprIndex) \
|
||||||
|
MPTR vaOriginalR1 = PPCInterpreter_getCurrentInstance()->gpr[1]; \
|
||||||
|
StackAllocator<ppc_va_list_reg_storage> va_list_storage; \
|
||||||
|
for(int i=3; i<=10; i++) va_list_storage->gpr_save_area[i-3] = PPCInterpreter_getCurrentInstance()->gpr[i]; \
|
||||||
|
for(int i=1; i<=8; i++) va_list_storage->fpr_save_area[i-1] = PPCInterpreter_getCurrentInstance()->fpr[i].fp0; \
|
||||||
|
va_list_storage->vargs.gprIndex = __gprIndex; \
|
||||||
|
va_list_storage->vargs.fprIndex = __fprIndex; \
|
||||||
|
va_list_storage->vargs.reg_save_area = (uint8be*)&va_list_storage; \
|
||||||
|
va_list_storage->vargs.overflow_arg_area = {vaOriginalR1 + 8}; \
|
||||||
|
ppc_va_list& vargs = va_list_storage->vargs;
|
||||||
|
|
||||||
|
enum class ppc_va_type
|
||||||
|
{
|
||||||
|
INT32 = 1,
|
||||||
|
INT64 = 2,
|
||||||
|
FLOAT_OR_DOUBLE = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void* _ppc_va_arg(ppc_va_list* vargs, ppc_va_type argType)
|
||||||
|
{
|
||||||
|
void* r;
|
||||||
|
switch ( argType )
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
cemu_assert_suspicious();
|
||||||
|
case ppc_va_type::INT32:
|
||||||
|
if ( vargs[0].gprIndex < 8u )
|
||||||
|
{
|
||||||
|
r = &vargs->reg_save_area[4 * vargs->gprIndex];
|
||||||
|
vargs->gprIndex++;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
r = vargs->overflow_arg_area;
|
||||||
|
vargs->overflow_arg_area += 4;
|
||||||
|
return r;
|
||||||
|
case ppc_va_type::INT64:
|
||||||
|
if ( (vargs->gprIndex & 1) != 0 )
|
||||||
|
vargs->gprIndex++;
|
||||||
|
if ( vargs->gprIndex < 8 )
|
||||||
|
{
|
||||||
|
r = &vargs->reg_save_area[4 * vargs->gprIndex];
|
||||||
|
vargs->gprIndex += 2;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
|
||||||
|
r = vargs->overflow_arg_area;
|
||||||
|
vargs->overflow_arg_area += 8;
|
||||||
|
return r;
|
||||||
|
case ppc_va_type::FLOAT_OR_DOUBLE:
|
||||||
|
if ( vargs->fprIndex < 8 )
|
||||||
|
{
|
||||||
|
r = &vargs->reg_save_area[0x20 + 8 * vargs->fprIndex];
|
||||||
|
vargs->fprIndex++;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
vargs->overflow_arg_area = {(vargs->overflow_arg_area.GetMPTR()+7) & 0xFFFFFFF8};
|
||||||
|
r = vargs->overflow_arg_area;
|
||||||
|
vargs->overflow_arg_area += 8;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
#include "Cafe/OS/common/OSCommon.h"
|
#include "Cafe/OS/common/OSCommon.h"
|
||||||
#include "Common/SysAllocator.h"
|
#include "Common/SysAllocator.h"
|
||||||
#include "Cafe/OS/RPL/rpl.h"
|
#include "Cafe/OS/RPL/rpl_symbol_storage.h"
|
||||||
|
|
||||||
#include "Cafe/OS/libs/coreinit/coreinit_Misc.h"
|
#include "Cafe/OS/libs/coreinit/coreinit_Misc.h"
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ sint32 ScoreStackTrace(OSThread_t* thread, MPTR sp)
|
|||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebugLogStackTrace(OSThread_t* thread, MPTR sp)
|
void DebugLogStackTrace(OSThread_t* thread, MPTR sp, bool printSymbols)
|
||||||
{
|
{
|
||||||
// sp might not point to a valid stackframe
|
// sp might not point to a valid stackframe
|
||||||
// scan stack and evaluate which sp is most likely the beginning of the stackframe
|
// scan stack and evaluate which sp is most likely the beginning of the stackframe
|
||||||
@ -107,7 +107,15 @@ void DebugLogStackTrace(OSThread_t* thread, MPTR sp)
|
|||||||
|
|
||||||
uint32 returnAddress = 0;
|
uint32 returnAddress = 0;
|
||||||
returnAddress = memory_readU32(nextStackPtr + 4);
|
returnAddress = memory_readU32(nextStackPtr + 4);
|
||||||
cemuLog_log(LogType::Force, fmt::format("SP {0:08x} ReturnAddr {1:08x}", nextStackPtr, returnAddress));
|
|
||||||
|
RPLStoredSymbol* symbol = nullptr;
|
||||||
|
if(printSymbols)
|
||||||
|
symbol = rplSymbolStorage_getByClosestAddress(returnAddress);
|
||||||
|
|
||||||
|
if(symbol)
|
||||||
|
cemuLog_log(LogType::Force, fmt::format("SP {:08x} ReturnAddr {:08x} ({}.{}+0x{:x})", nextStackPtr, returnAddress, (const char*)symbol->libName, (const char*)symbol->symbolName, returnAddress - symbol->address));
|
||||||
|
else
|
||||||
|
cemuLog_log(LogType::Force, fmt::format("SP {:08x} ReturnAddr {:08x}", nextStackPtr, returnAddress));
|
||||||
|
|
||||||
currentStackPtr = nextStackPtr;
|
currentStackPtr = nextStackPtr;
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
#include "Cafe/HW/Espresso/PPCCallback.h"
|
#include "Cafe/HW/Espresso/PPCCallback.h"
|
||||||
#include "Cafe/OS/libs/coreinit/coreinit_MEM_ExpHeap.h"
|
#include "Cafe/OS/libs/coreinit/coreinit_MEM_ExpHeap.h"
|
||||||
|
|
||||||
void DebugLogStackTrace(OSThread_t* thread, MPTR sp);
|
|
||||||
|
|
||||||
#define EXP_HEAP_GET_FROM_FREE_BLOCKCHAIN(__blockchain__) (MEMExpHeapHead2*)((uintptr_t)__blockchain__ - offsetof(MEMExpHeapHead2, expHeapHead) - offsetof(MEMExpHeapHead40_t, chainFreeBlocks))
|
#define EXP_HEAP_GET_FROM_FREE_BLOCKCHAIN(__blockchain__) (MEMExpHeapHead2*)((uintptr_t)__blockchain__ - offsetof(MEMExpHeapHead2, expHeapHead) - offsetof(MEMExpHeapHead40_t, chainFreeBlocks))
|
||||||
|
|
||||||
namespace coreinit
|
namespace coreinit
|
||||||
|
@ -7,14 +7,9 @@
|
|||||||
|
|
||||||
namespace coreinit
|
namespace coreinit
|
||||||
{
|
{
|
||||||
|
sint32 ppc_vprintf(const char* formatStr, char* strOut, sint32 maxLength, ppc_va_list* vargs)
|
||||||
/* coreinit logging and string format */
|
|
||||||
|
|
||||||
sint32 ppcSprintf(const char* formatStr, char* strOut, sint32 maxLength, PPCInterpreter_t* hCPU, sint32 initialParamIndex)
|
|
||||||
{
|
{
|
||||||
char tempStr[4096];
|
char tempStr[4096];
|
||||||
sint32 integerParamIndex = initialParamIndex;
|
|
||||||
sint32 floatParamIndex = 0;
|
|
||||||
sint32 writeIndex = 0;
|
sint32 writeIndex = 0;
|
||||||
while (*formatStr)
|
while (*formatStr)
|
||||||
{
|
{
|
||||||
@ -101,8 +96,7 @@ namespace coreinit
|
|||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU32(hCPU, integerParamIndex));
|
sint32 tempLen = sprintf(tempStr, tempFormat, (uint32)*(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32));
|
||||||
integerParamIndex++;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -120,13 +114,12 @@ namespace coreinit
|
|||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
MPTR strOffset = PPCInterpreter_getCallParamU32(hCPU, integerParamIndex);
|
MPTR strOffset = *(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32);
|
||||||
sint32 tempLen = 0;
|
sint32 tempLen = 0;
|
||||||
if (strOffset == MPTR_NULL)
|
if (strOffset == MPTR_NULL)
|
||||||
tempLen = sprintf(tempStr, "NULL");
|
tempLen = sprintf(tempStr, "NULL");
|
||||||
else
|
else
|
||||||
tempLen = sprintf(tempStr, tempFormat, memory_getPointerFromVirtualOffset(strOffset));
|
tempLen = sprintf(tempStr, tempFormat, memory_getPointerFromVirtualOffset(strOffset));
|
||||||
integerParamIndex++;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -136,25 +129,6 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
strOut[std::min(maxLength - 1, writeIndex)] = '\0';
|
strOut[std::min(maxLength - 1, writeIndex)] = '\0';
|
||||||
}
|
}
|
||||||
else if (*formatStr == 'f')
|
|
||||||
{
|
|
||||||
// float
|
|
||||||
formatStr++;
|
|
||||||
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
|
|
||||||
if ((formatStr - formatStart) < sizeof(tempFormat))
|
|
||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
|
||||||
else
|
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, (float)hCPU->fpr[1 + floatParamIndex].fp0);
|
|
||||||
floatParamIndex++;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
|
||||||
{
|
|
||||||
if (writeIndex >= maxLength)
|
|
||||||
break;
|
|
||||||
strOut[writeIndex] = tempStr[i];
|
|
||||||
writeIndex++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (*formatStr == 'c')
|
else if (*formatStr == 'c')
|
||||||
{
|
{
|
||||||
// character
|
// character
|
||||||
@ -164,8 +138,24 @@ namespace coreinit
|
|||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU32(hCPU, integerParamIndex));
|
sint32 tempLen = sprintf(tempStr, tempFormat, (uint32)*(uint32be*)_ppc_va_arg(vargs, ppc_va_type::INT32));
|
||||||
integerParamIndex++;
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
|
{
|
||||||
|
if (writeIndex >= maxLength)
|
||||||
|
break;
|
||||||
|
strOut[writeIndex] = tempStr[i];
|
||||||
|
writeIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (*formatStr == 'f' || *formatStr == 'g' || *formatStr == 'G')
|
||||||
|
{
|
||||||
|
formatStr++;
|
||||||
|
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
|
||||||
|
if ((formatStr - formatStart) < sizeof(tempFormat))
|
||||||
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
|
else
|
||||||
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
|
sint32 tempLen = sprintf(tempStr, tempFormat, (double)*(betype<double>*)_ppc_va_arg(vargs, ppc_va_type::FLOAT_OR_DOUBLE));
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -183,8 +173,7 @@ namespace coreinit
|
|||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, (double)hCPU->fpr[1 + floatParamIndex].fp0);
|
sint32 tempLen = sprintf(tempStr, tempFormat, (double)*(betype<double>*)_ppc_va_arg(vargs, ppc_va_type::FLOAT_OR_DOUBLE));
|
||||||
floatParamIndex++;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -196,16 +185,13 @@ namespace coreinit
|
|||||||
else if ((formatStr[0] == 'l' && formatStr[1] == 'l' && (formatStr[2] == 'x' || formatStr[2] == 'X')))
|
else if ((formatStr[0] == 'l' && formatStr[1] == 'l' && (formatStr[2] == 'x' || formatStr[2] == 'X')))
|
||||||
{
|
{
|
||||||
formatStr += 3;
|
formatStr += 3;
|
||||||
// double (64bit)
|
// 64bit int
|
||||||
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
|
strncpy(tempFormat, formatStart, std::min((std::ptrdiff_t)sizeof(tempFormat) - 1, formatStr - formatStart));
|
||||||
if ((formatStr - formatStart) < sizeof(tempFormat))
|
if ((formatStr - formatStart) < sizeof(tempFormat))
|
||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
if (integerParamIndex & 1)
|
sint32 tempLen = sprintf(tempStr, tempFormat, (uint64)*(uint64be*)_ppc_va_arg(vargs, ppc_va_type::INT64));
|
||||||
integerParamIndex++;
|
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU64(hCPU, integerParamIndex));
|
|
||||||
integerParamIndex += 2;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -223,10 +209,7 @@ namespace coreinit
|
|||||||
tempFormat[(formatStr - formatStart)] = '\0';
|
tempFormat[(formatStr - formatStart)] = '\0';
|
||||||
else
|
else
|
||||||
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
tempFormat[sizeof(tempFormat) - 1] = '\0';
|
||||||
if (integerParamIndex & 1)
|
sint32 tempLen = sprintf(tempStr, tempFormat, (sint64)*(sint64be*)_ppc_va_arg(vargs, ppc_va_type::INT64));
|
||||||
integerParamIndex++;
|
|
||||||
sint32 tempLen = sprintf(tempStr, tempFormat, PPCInterpreter_getCallParamU64(hCPU, integerParamIndex));
|
|
||||||
integerParamIndex += 2;
|
|
||||||
for (sint32 i = 0; i < tempLen; i++)
|
for (sint32 i = 0; i < tempLen; i++)
|
||||||
{
|
{
|
||||||
if (writeIndex >= maxLength)
|
if (writeIndex >= maxLength)
|
||||||
@ -255,9 +238,12 @@ namespace coreinit
|
|||||||
return std::min(writeIndex, maxLength - 1);
|
return std::min(writeIndex, maxLength - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* coreinit logging and string format */
|
||||||
|
|
||||||
sint32 __os_snprintf(char* outputStr, sint32 maxLength, const char* formatStr)
|
sint32 __os_snprintf(char* outputStr, sint32 maxLength, const char* formatStr)
|
||||||
{
|
{
|
||||||
sint32 r = ppcSprintf(formatStr, outputStr, maxLength, PPCInterpreter_getCurrentInstance(), 3);
|
ppc_define_va_list(3, 0);
|
||||||
|
sint32 r = ppc_vprintf(formatStr, outputStr, maxLength, &vargs);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,32 +308,40 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSReport(const char* format)
|
void COSVReport(COSReportModule module, COSReportLevel level, const char* format, ppc_va_list* vargs)
|
||||||
{
|
{
|
||||||
char buffer[1024 * 2];
|
char tmpBuffer[1024];
|
||||||
sint32 len = ppcSprintf(format, buffer, sizeof(buffer), PPCInterpreter_getCurrentInstance(), 1);
|
sint32 len = ppc_vprintf(format, tmpBuffer, sizeof(tmpBuffer), vargs);
|
||||||
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len);
|
WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSVReport(const char* format, MPTR vaArgs)
|
void OSReport(const char* format)
|
||||||
{
|
{
|
||||||
cemu_assert_unimplemented();
|
ppc_define_va_list(1, 0);
|
||||||
|
COSVReport(COSReportModule::coreinit, COSReportLevel::Info, format, &vargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OSVReport(const char* format, ppc_va_list* vargs)
|
||||||
|
{
|
||||||
|
COSVReport(COSReportModule::coreinit, COSReportLevel::Info, format, vargs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void COSWarn(int moduleId, const char* format)
|
void COSWarn(int moduleId, const char* format)
|
||||||
{
|
{
|
||||||
char buffer[1024 * 2];
|
ppc_define_va_list(2, 0);
|
||||||
int prefixLen = sprintf(buffer, "[COSWarn-%d] ", moduleId);
|
char tmpBuffer[1024];
|
||||||
sint32 len = ppcSprintf(format, buffer + prefixLen, sizeof(buffer) - prefixLen, PPCInterpreter_getCurrentInstance(), 2);
|
int prefixLen = sprintf(tmpBuffer, "[COSWarn-%d] ", moduleId);
|
||||||
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len + prefixLen);
|
sint32 len = ppc_vprintf(format, tmpBuffer + prefixLen, sizeof(tmpBuffer) - prefixLen, &vargs);
|
||||||
|
WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len + prefixLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSLogPrintf(int ukn1, int ukn2, int ukn3, const char* format)
|
void OSLogPrintf(int ukn1, int ukn2, int ukn3, const char* format)
|
||||||
{
|
{
|
||||||
char buffer[1024 * 2];
|
ppc_define_va_list(4, 0);
|
||||||
int prefixLen = sprintf(buffer, "[OSLogPrintf-%d-%d-%d] ", ukn1, ukn2, ukn3);
|
char tmpBuffer[1024];
|
||||||
sint32 len = ppcSprintf(format, buffer + prefixLen, sizeof(buffer) - prefixLen, PPCInterpreter_getCurrentInstance(), 4);
|
int prefixLen = sprintf(tmpBuffer, "[OSLogPrintf-%d-%d-%d] ", ukn1, ukn2, ukn3);
|
||||||
WriteCafeConsole(CafeLogType::OSCONSOLE, buffer, len + prefixLen);
|
sint32 len = ppc_vprintf(format, tmpBuffer + prefixLen, sizeof(tmpBuffer) - prefixLen, &vargs);
|
||||||
|
WriteCafeConsole(CafeLogType::OSCONSOLE, tmpBuffer, len + prefixLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OSConsoleWrite(const char* strPtr, sint32 length)
|
void OSConsoleWrite(const char* strPtr, sint32 length)
|
||||||
@ -562,9 +556,11 @@ namespace coreinit
|
|||||||
s_transitionToForeground = false;
|
s_transitionToForeground = false;
|
||||||
|
|
||||||
cafeExportRegister("coreinit", __os_snprintf, LogType::Placeholder);
|
cafeExportRegister("coreinit", __os_snprintf, LogType::Placeholder);
|
||||||
|
|
||||||
|
cafeExportRegister("coreinit", COSVReport, LogType::Placeholder);
|
||||||
|
cafeExportRegister("coreinit", COSWarn, LogType::Placeholder);
|
||||||
cafeExportRegister("coreinit", OSReport, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSReport, LogType::Placeholder);
|
||||||
cafeExportRegister("coreinit", OSVReport, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSVReport, LogType::Placeholder);
|
||||||
cafeExportRegister("coreinit", COSWarn, LogType::Placeholder);
|
|
||||||
cafeExportRegister("coreinit", OSLogPrintf, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSLogPrintf, LogType::Placeholder);
|
||||||
cafeExportRegister("coreinit", OSConsoleWrite, LogType::Placeholder);
|
cafeExportRegister("coreinit", OSConsoleWrite, LogType::Placeholder);
|
||||||
|
|
||||||
|
@ -26,5 +26,19 @@ namespace coreinit
|
|||||||
uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3);
|
uint32 OSDriver_Register(uint32 moduleHandle, sint32 priority, OSDriverInterface* driverCallbacks, sint32 driverId, uint32be* outUkn1, uint32be* outUkn2, uint32be* outUkn3);
|
||||||
uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId);
|
uint32 OSDriver_Deregister(uint32 moduleHandle, sint32 driverId);
|
||||||
|
|
||||||
|
enum class COSReportModule
|
||||||
|
{
|
||||||
|
coreinit = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class COSReportLevel
|
||||||
|
{
|
||||||
|
Error = 0,
|
||||||
|
Warn = 1,
|
||||||
|
Info = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
sint32 ppc_vprintf(const char* formatStr, char* strOut, sint32 maxLength, ppc_va_list* vargs);
|
||||||
|
|
||||||
void miscInit();
|
void miscInit();
|
||||||
};
|
};
|
@ -140,7 +140,7 @@ namespace coreinit
|
|||||||
// we are in single-core mode and the lock will never be released unless we let other threads resume work
|
// we are in single-core mode and the lock will never be released unless we let other threads resume work
|
||||||
// to avoid an infinite loop we have no choice but to yield the thread even it is in an uninterruptible state
|
// to avoid an infinite loop we have no choice but to yield the thread even it is in an uninterruptible state
|
||||||
if( !OSIsInterruptEnabled() )
|
if( !OSIsInterruptEnabled() )
|
||||||
cemuLog_log(LogType::APIErrors, "OSUninterruptibleSpinLock_Acquire(): Lock is occupied which requires a wait but current thread is already in an uninterruptible state (Avoid cascaded OSDisableInterrupts and/or OSUninterruptibleSpinLock)");
|
cemuLog_logOnce(LogType::APIErrors, "OSUninterruptibleSpinLock_Acquire(): Lock is occupied which requires a wait but current thread is already in an uninterruptible state (Avoid cascaded OSDisableInterrupts and/or OSUninterruptibleSpinLock)");
|
||||||
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
while (!spinlock->ownerThread.atomic_compare_exchange(nullptr, currentThread))
|
||||||
{
|
{
|
||||||
OSYieldThread();
|
OSYieldThread();
|
||||||
|
@ -310,7 +310,7 @@ namespace coreinit
|
|||||||
currentThread->mutexQueue.removeMutex(mutex);
|
currentThread->mutexQueue.removeMutex(mutex);
|
||||||
mutex->owner = nullptr;
|
mutex->owner = nullptr;
|
||||||
if (!mutex->threadQueue.isEmpty())
|
if (!mutex->threadQueue.isEmpty())
|
||||||
mutex->threadQueue.wakeupSingleThreadWaitQueue(true);
|
mutex->threadQueue.wakeupSingleThreadWaitQueue(true, true);
|
||||||
}
|
}
|
||||||
// currentThread->cancelState = currentThread->cancelState & ~0x10000;
|
// currentThread->cancelState = currentThread->cancelState & ~0x10000;
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,10 @@ namespace coreinit
|
|||||||
return coreinit::MEMAllocFromExpHeapEx(_sysHeapHandle, size, alignment);
|
return coreinit::MEMAllocFromExpHeapEx(_sysHeapHandle, size, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_OSAllocFromSystem(PPCInterpreter_t* hCPU)
|
void OSFreeToSystem(void* ptr)
|
||||||
{
|
{
|
||||||
ppcDefineParamU32(size, 0);
|
_sysHeapFreeCounter++;
|
||||||
ppcDefineParamS32(alignment, 1);
|
coreinit::MEMFreeToExpHeap(_sysHeapHandle, ptr);
|
||||||
MEMPTR<void> mem = OSAllocFromSystem(size, alignment);
|
|
||||||
cemuLog_logDebug(LogType::Force, "OSAllocFromSystem(0x{:x}, {}) -> 0x{:08x}", size, alignment, mem.GetMPTR());
|
|
||||||
osLib_returnFromFunction(hCPU, mem.GetMPTR());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitSysHeap()
|
void InitSysHeap()
|
||||||
@ -34,7 +31,8 @@ namespace coreinit
|
|||||||
|
|
||||||
void InitializeSysHeap()
|
void InitializeSysHeap()
|
||||||
{
|
{
|
||||||
osLib_addFunction("coreinit", "OSAllocFromSystem", export_OSAllocFromSystem);
|
cafeExportRegister("h264", OSAllocFromSystem, LogType::CoreinitMem);
|
||||||
|
cafeExportRegister("h264", OSFreeToSystem, LogType::CoreinitMem);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,8 @@ namespace coreinit
|
|||||||
{
|
{
|
||||||
void InitSysHeap();
|
void InitSysHeap();
|
||||||
|
|
||||||
|
void* OSAllocFromSystem(uint32 size, uint32 alignment);
|
||||||
|
void OSFreeToSystem(void* ptr);
|
||||||
|
|
||||||
void InitializeSysHeap();
|
void InitializeSysHeap();
|
||||||
}
|
}
|
@ -758,14 +758,14 @@ namespace coreinit
|
|||||||
}
|
}
|
||||||
|
|
||||||
// returns true if thread runs on same core and has higher priority
|
// returns true if thread runs on same core and has higher priority
|
||||||
bool __OSCoreShouldSwitchToThread(OSThread_t* currentThread, OSThread_t* newThread)
|
bool __OSCoreShouldSwitchToThread(OSThread_t* currentThread, OSThread_t* newThread, bool sharedPriorityAndAffinityWorkaround)
|
||||||
{
|
{
|
||||||
uint32 coreIndex = OSGetCoreId();
|
uint32 coreIndex = OSGetCoreId();
|
||||||
if (!newThread->context.hasCoreAffinitySet(coreIndex))
|
if (!newThread->context.hasCoreAffinitySet(coreIndex))
|
||||||
return false;
|
return false;
|
||||||
// special case: if current and new thread are running only on the same core then reschedule even if priority is equal
|
// special case: if current and new thread are running only on the same core then reschedule even if priority is equal
|
||||||
// this resolves a deadlock in Just Dance 2019 where one thread would always reacquire the same mutex within it's timeslice, blocking another thread on the same core from acquiring it
|
// this resolves a deadlock in Just Dance 2019 where one thread would always reacquire the same mutex within it's timeslice, blocking another thread on the same core from acquiring it
|
||||||
if ((1<<coreIndex) == newThread->context.affinity && currentThread->context.affinity == newThread->context.affinity && currentThread->effectivePriority == newThread->effectivePriority)
|
if (sharedPriorityAndAffinityWorkaround && (1<<coreIndex) == newThread->context.affinity && currentThread->context.affinity == newThread->context.affinity && currentThread->effectivePriority == newThread->effectivePriority)
|
||||||
return true;
|
return true;
|
||||||
// otherwise reschedule if new thread has higher priority
|
// otherwise reschedule if new thread has higher priority
|
||||||
return newThread->effectivePriority < currentThread->effectivePriority;
|
return newThread->effectivePriority < currentThread->effectivePriority;
|
||||||
@ -791,7 +791,7 @@ namespace coreinit
|
|||||||
// todo - only set this once?
|
// todo - only set this once?
|
||||||
thread->wakeUpTime = PPCInterpreter_getMainCoreCycleCounter();
|
thread->wakeUpTime = PPCInterpreter_getMainCoreCycleCounter();
|
||||||
// reschedule if thread has higher priority
|
// reschedule if thread has higher priority
|
||||||
if (PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread))
|
if (PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread, false))
|
||||||
PPCCore_switchToSchedulerWithLock();
|
PPCCore_switchToSchedulerWithLock();
|
||||||
}
|
}
|
||||||
return previousSuspendCount;
|
return previousSuspendCount;
|
||||||
@ -948,7 +948,7 @@ namespace coreinit
|
|||||||
OSThread_t* currentThread = OSGetCurrentThread();
|
OSThread_t* currentThread = OSGetCurrentThread();
|
||||||
if (currentThread && currentThread != thread)
|
if (currentThread && currentThread != thread)
|
||||||
{
|
{
|
||||||
if (__OSCoreShouldSwitchToThread(currentThread, thread))
|
if (__OSCoreShouldSwitchToThread(currentThread, thread, false))
|
||||||
PPCCore_switchToSchedulerWithLock();
|
PPCCore_switchToSchedulerWithLock();
|
||||||
}
|
}
|
||||||
__OSUnlockScheduler();
|
__OSUnlockScheduler();
|
||||||
@ -1608,21 +1608,3 @@ namespace coreinit
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void coreinit_suspendThread(OSThread_t* OSThreadBE, sint32 count)
|
|
||||||
{
|
|
||||||
// for legacy source
|
|
||||||
OSThreadBE->suspendCounter += count;
|
|
||||||
}
|
|
||||||
|
|
||||||
void coreinit_resumeThread(OSThread_t* OSThreadBE, sint32 count)
|
|
||||||
{
|
|
||||||
__OSLockScheduler();
|
|
||||||
coreinit::__OSResumeThreadInternal(OSThreadBE, count);
|
|
||||||
__OSUnlockScheduler();
|
|
||||||
}
|
|
||||||
|
|
||||||
OSThread_t* coreinitThread_getCurrentThreadDepr(PPCInterpreter_t* hCPU)
|
|
||||||
{
|
|
||||||
return coreinit::__currentCoreThread[PPCInterpreter_getCoreIndex(hCPU)];
|
|
||||||
}
|
|
||||||
|
@ -126,8 +126,8 @@ namespace coreinit
|
|||||||
|
|
||||||
// counterparts for queueAndWait
|
// counterparts for queueAndWait
|
||||||
void cancelWait(OSThread_t* thread);
|
void cancelWait(OSThread_t* thread);
|
||||||
void wakeupEntireWaitQueue(bool reschedule);
|
void wakeupEntireWaitQueue(bool reschedule, bool sharedPriorityAndAffinityWorkaround = false);
|
||||||
void wakeupSingleThreadWaitQueue(bool reschedule);
|
void wakeupSingleThreadWaitQueue(bool reschedule, bool sharedPriorityAndAffinityWorkaround = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OSThread_t* takeFirstFromQueue(size_t linkOffset)
|
OSThread_t* takeFirstFromQueue(size_t linkOffset)
|
||||||
@ -611,7 +611,7 @@ namespace coreinit
|
|||||||
|
|
||||||
// internal
|
// internal
|
||||||
void __OSAddReadyThreadToRunQueue(OSThread_t* thread);
|
void __OSAddReadyThreadToRunQueue(OSThread_t* thread);
|
||||||
bool __OSCoreShouldSwitchToThread(OSThread_t* currentThread, OSThread_t* newThread);
|
bool __OSCoreShouldSwitchToThread(OSThread_t* currentThread, OSThread_t* newThread, bool sharedPriorityAndAffinityWorkaround);
|
||||||
void __OSQueueThreadDeallocation(OSThread_t* thread);
|
void __OSQueueThreadDeallocation(OSThread_t* thread);
|
||||||
|
|
||||||
bool __OSIsThreadActive(OSThread_t* thread);
|
bool __OSIsThreadActive(OSThread_t* thread);
|
||||||
@ -621,11 +621,6 @@ namespace coreinit
|
|||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
// deprecated / clean up required
|
// deprecated / clean up required
|
||||||
void coreinit_suspendThread(OSThread_t* OSThreadBE, sint32 count = 1);
|
|
||||||
void coreinit_resumeThread(OSThread_t* OSThreadBE, sint32 count = 1);
|
|
||||||
|
|
||||||
OSThread_t* coreinitThread_getCurrentThreadDepr(PPCInterpreter_t* hCPU);
|
|
||||||
|
|
||||||
extern MPTR activeThread[256];
|
extern MPTR activeThread[256];
|
||||||
extern sint32 activeThreadCount;
|
extern sint32 activeThreadCount;
|
||||||
|
|
||||||
|
@ -128,7 +128,8 @@ namespace coreinit
|
|||||||
|
|
||||||
// counterpart for queueAndWait
|
// counterpart for queueAndWait
|
||||||
// if reschedule is true then scheduler will switch to woken up thread (if it is runnable on the same core)
|
// if reschedule is true then scheduler will switch to woken up thread (if it is runnable on the same core)
|
||||||
void OSThreadQueueInternal::wakeupEntireWaitQueue(bool reschedule)
|
// sharedPriorityAndAffinityWorkaround is currently a hack/placeholder for some special cases. A proper fix likely involves handling all the nuances of thread effective priority
|
||||||
|
void OSThreadQueueInternal::wakeupEntireWaitQueue(bool reschedule, bool sharedPriorityAndAffinityWorkaround)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(__OSHasSchedulerLock());
|
cemu_assert_debug(__OSHasSchedulerLock());
|
||||||
bool shouldReschedule = false;
|
bool shouldReschedule = false;
|
||||||
@ -139,7 +140,7 @@ namespace coreinit
|
|||||||
thread->state = OSThread_t::THREAD_STATE::STATE_READY;
|
thread->state = OSThread_t::THREAD_STATE::STATE_READY;
|
||||||
thread->currentWaitQueue = nullptr;
|
thread->currentWaitQueue = nullptr;
|
||||||
coreinit::__OSAddReadyThreadToRunQueue(thread);
|
coreinit::__OSAddReadyThreadToRunQueue(thread);
|
||||||
if (reschedule && thread->suspendCounter == 0 && PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread))
|
if (reschedule && thread->suspendCounter == 0 && PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread, sharedPriorityAndAffinityWorkaround))
|
||||||
shouldReschedule = true;
|
shouldReschedule = true;
|
||||||
}
|
}
|
||||||
if (shouldReschedule)
|
if (shouldReschedule)
|
||||||
@ -148,7 +149,7 @@ namespace coreinit
|
|||||||
|
|
||||||
// counterpart for queueAndWait
|
// counterpart for queueAndWait
|
||||||
// if reschedule is true then scheduler will switch to woken up thread (if it is runnable on the same core)
|
// if reschedule is true then scheduler will switch to woken up thread (if it is runnable on the same core)
|
||||||
void OSThreadQueueInternal::wakeupSingleThreadWaitQueue(bool reschedule)
|
void OSThreadQueueInternal::wakeupSingleThreadWaitQueue(bool reschedule, bool sharedPriorityAndAffinityWorkaround)
|
||||||
{
|
{
|
||||||
cemu_assert_debug(__OSHasSchedulerLock());
|
cemu_assert_debug(__OSHasSchedulerLock());
|
||||||
OSThread_t* thread = takeFirstFromQueue(offsetof(OSThread_t, waitQueueLink));
|
OSThread_t* thread = takeFirstFromQueue(offsetof(OSThread_t, waitQueueLink));
|
||||||
@ -159,7 +160,7 @@ namespace coreinit
|
|||||||
thread->state = OSThread_t::THREAD_STATE::STATE_READY;
|
thread->state = OSThread_t::THREAD_STATE::STATE_READY;
|
||||||
thread->currentWaitQueue = nullptr;
|
thread->currentWaitQueue = nullptr;
|
||||||
coreinit::__OSAddReadyThreadToRunQueue(thread);
|
coreinit::__OSAddReadyThreadToRunQueue(thread);
|
||||||
if (reschedule && thread->suspendCounter == 0 && PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread))
|
if (reschedule && thread->suspendCounter == 0 && PPCInterpreter_getCurrentInstance() && __OSCoreShouldSwitchToThread(coreinit::OSGetCurrentThread(), thread, sharedPriorityAndAffinityWorkaround))
|
||||||
shouldReschedule = true;
|
shouldReschedule = true;
|
||||||
}
|
}
|
||||||
if (shouldReschedule)
|
if (shouldReschedule)
|
||||||
|
@ -154,14 +154,6 @@ namespace GX2
|
|||||||
return gx2WriteGatherPipe.displayListStart[coreIndex] != MPTR_NULL;
|
return gx2WriteGatherPipe.displayListStart[coreIndex] != MPTR_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GX2WriteGather_isDisplayListActive()
|
|
||||||
{
|
|
||||||
uint32 coreIndex = coreinit::OSGetCoreId();
|
|
||||||
if (gx2WriteGatherPipe.displayListStart[coreIndex] != MPTR_NULL)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 GX2WriteGather_getReadWriteDistance()
|
uint32 GX2WriteGather_getReadWriteDistance()
|
||||||
{
|
{
|
||||||
uint32 coreIndex = sGX2MainCoreIndex;
|
uint32 coreIndex = sGX2MainCoreIndex;
|
||||||
|
@ -84,8 +84,6 @@ inline void gx2WriteGather_submit(Targs... args)
|
|||||||
|
|
||||||
namespace GX2
|
namespace GX2
|
||||||
{
|
{
|
||||||
|
|
||||||
bool GX2WriteGather_isDisplayListActive();
|
|
||||||
uint32 GX2WriteGather_getReadWriteDistance();
|
uint32 GX2WriteGather_getReadWriteDistance();
|
||||||
void GX2WriteGather_checkAndInsertWrapAroundMark();
|
void GX2WriteGather_checkAndInsertWrapAroundMark();
|
||||||
|
|
||||||
@ -96,6 +94,8 @@ namespace GX2
|
|||||||
void GX2CallDisplayList(MPTR addr, uint32 size);
|
void GX2CallDisplayList(MPTR addr, uint32 size);
|
||||||
void GX2DirectCallDisplayList(void* addr, uint32 size);
|
void GX2DirectCallDisplayList(void* addr, uint32 size);
|
||||||
|
|
||||||
|
bool GX2GetDisplayListWriteStatus();
|
||||||
|
|
||||||
void GX2Init_writeGather();
|
void GX2Init_writeGather();
|
||||||
void GX2CommandInit();
|
void GX2CommandInit();
|
||||||
void GX2CommandResetToDefaultState();
|
void GX2CommandResetToDefaultState();
|
||||||
|
@ -291,8 +291,7 @@ void gx2Export_GX2SetDefaultState(PPCInterpreter_t* hCPU)
|
|||||||
void _GX2ContextCreateRestoreStateDL(GX2ContextState_t* gx2ContextState)
|
void _GX2ContextCreateRestoreStateDL(GX2ContextState_t* gx2ContextState)
|
||||||
{
|
{
|
||||||
// begin display list
|
// begin display list
|
||||||
if (GX2::GX2WriteGather_isDisplayListActive())
|
cemu_assert_debug(!GX2::GX2GetDisplayListWriteStatus()); // must not already be writing to a display list
|
||||||
assert_dbg();
|
|
||||||
GX2::GX2BeginDisplayList((void*)gx2ContextState->loadDL_buffer, sizeof(gx2ContextState->loadDL_buffer));
|
GX2::GX2BeginDisplayList((void*)gx2ContextState->loadDL_buffer, sizeof(gx2ContextState->loadDL_buffer));
|
||||||
_GX2Context_WriteCmdRestoreState(gx2ContextState, 0);
|
_GX2Context_WriteCmdRestoreState(gx2ContextState, 0);
|
||||||
uint32 displayListSize = GX2::GX2EndDisplayList((void*)gx2ContextState->loadDL_buffer);
|
uint32 displayListSize = GX2::GX2EndDisplayList((void*)gx2ContextState->loadDL_buffer);
|
||||||
|
@ -426,7 +426,7 @@ namespace GX2
|
|||||||
}
|
}
|
||||||
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
if((aluRegisterOffset+sizeInU32s) > 0x400)
|
||||||
{
|
{
|
||||||
cemuLog_logOnce(LogType::APIErrors, "GX2SetVertexUniformReg values are out of range (offset {} + size {} must be equal or smaller than 0x400)", aluRegisterOffset, sizeInU32s);
|
cemuLog_logOnce(LogType::APIErrors, "GX2SetVertexUniformReg values are out of range (offset {} + size {} must be equal or smaller than 1024)", aluRegisterOffset, sizeInU32s);
|
||||||
}
|
}
|
||||||
if( (sizeInU32s&3) != 0)
|
if( (sizeInU32s&3) != 0)
|
||||||
{
|
{
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
#include "Cafe/OS/common/OSCommon.h"
|
#include "Cafe/OS/common/OSCommon.h"
|
||||||
#include "Cafe/HW/Espresso/PPCCallback.h"
|
#include "Cafe/HW/Espresso/PPCCallback.h"
|
||||||
#include "Cafe/OS/libs/h264_avc/parser/H264Parser.h"
|
#include "Cafe/OS/libs/h264_avc/parser/H264Parser.h"
|
||||||
|
#include "Cafe/OS/libs/h264_avc/H264DecInternal.h"
|
||||||
#include "util/highresolutiontimer/HighResolutionTimer.h"
|
#include "util/highresolutiontimer/HighResolutionTimer.h"
|
||||||
#include "Cafe/CafeSystem.h"
|
#include "Cafe/CafeSystem.h"
|
||||||
|
|
||||||
#include "h264dec.h"
|
#include "h264dec.h"
|
||||||
|
|
||||||
extern "C"
|
|
||||||
{
|
|
||||||
#include "../dependencies/ih264d/common/ih264_typedefs.h"
|
|
||||||
#include "../dependencies/ih264d/decoder/ih264d.h"
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class H264DEC_STATUS : uint32
|
enum class H264DEC_STATUS : uint32
|
||||||
{
|
{
|
||||||
SUCCESS = 0x0,
|
SUCCESS = 0x0,
|
||||||
@ -33,10 +28,35 @@ namespace H264
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct H264Context
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> ptr{ nullptr };
|
||||||
|
uint32be length{ 0 };
|
||||||
|
float64be timestamp;
|
||||||
|
}BitStream;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
MEMPTR<void> outputFunc{ nullptr };
|
||||||
|
uint8be outputPerFrame{ 0 }; // whats the default?
|
||||||
|
MEMPTR<void> userMemoryParam{ nullptr };
|
||||||
|
}Param;
|
||||||
|
// misc
|
||||||
|
uint32be sessionHandle;
|
||||||
|
|
||||||
|
// decoder state
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32 numFramesInFlight{0};
|
||||||
|
}decoderState;
|
||||||
|
};
|
||||||
|
|
||||||
uint32 H264DECMemoryRequirement(uint32 codecProfile, uint32 codecLevel, uint32 width, uint32 height, uint32be* sizeRequirementOut)
|
uint32 H264DECMemoryRequirement(uint32 codecProfile, uint32 codecLevel, uint32 width, uint32 height, uint32be* sizeRequirementOut)
|
||||||
{
|
{
|
||||||
if (H264_IsBotW())
|
if (H264_IsBotW())
|
||||||
{
|
{
|
||||||
|
static_assert(sizeof(H264Context) < 256);
|
||||||
*sizeRequirementOut = 256;
|
*sizeRequirementOut = 256;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -169,590 +189,47 @@ namespace H264
|
|||||||
return H264DEC_STATUS::BAD_STREAM;
|
return H264DEC_STATUS::BAD_STREAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct H264Context
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
MEMPTR<void> ptr{ nullptr };
|
|
||||||
uint32be length{ 0 };
|
|
||||||
float64be timestamp;
|
|
||||||
}BitStream;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
MEMPTR<void> outputFunc{ nullptr };
|
|
||||||
uint8be outputPerFrame{ 0 }; // whats the default?
|
|
||||||
MEMPTR<void> userMemoryParam{ nullptr };
|
|
||||||
}Param;
|
|
||||||
// misc
|
|
||||||
uint32be sessionHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
class H264AVCDecoder
|
|
||||||
{
|
|
||||||
static void* ivd_aligned_malloc(void* ctxt, WORD32 alignment, WORD32 size)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
return _aligned_malloc(size, alignment);
|
|
||||||
#else
|
|
||||||
// alignment is atleast sizeof(void*)
|
|
||||||
alignment = std::max<WORD32>(alignment, sizeof(void*));
|
|
||||||
|
|
||||||
//smallest multiple of 2 at least as large as alignment
|
|
||||||
alignment--;
|
|
||||||
alignment |= alignment << 1;
|
|
||||||
alignment |= alignment >> 1;
|
|
||||||
alignment |= alignment >> 2;
|
|
||||||
alignment |= alignment >> 4;
|
|
||||||
alignment |= alignment >> 8;
|
|
||||||
alignment |= alignment >> 16;
|
|
||||||
alignment ^= (alignment >> 1);
|
|
||||||
|
|
||||||
void* temp;
|
|
||||||
posix_memalign(&temp, (size_t)alignment, (size_t)size);
|
|
||||||
return temp;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ivd_aligned_free(void* ctxt, void* buf)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
_aligned_free(buf);
|
|
||||||
#else
|
|
||||||
free(buf);
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct DecodeResult
|
|
||||||
{
|
|
||||||
bool frameReady{ false };
|
|
||||||
double timestamp;
|
|
||||||
void* imageOutput;
|
|
||||||
ivd_video_decode_op_t decodeOutput;
|
|
||||||
};
|
|
||||||
|
|
||||||
void Init(bool isBufferedMode)
|
|
||||||
{
|
|
||||||
ih264d_create_ip_t s_create_ip{ 0 };
|
|
||||||
ih264d_create_op_t s_create_op{ 0 };
|
|
||||||
|
|
||||||
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t);
|
|
||||||
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 1; // shared display buffer mode -> We give the decoder a list of buffers that it will use (?)
|
|
||||||
|
|
||||||
s_create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t);
|
|
||||||
s_create_ip.s_ivd_create_ip_t.e_output_format = IV_YUV_420SP_UV;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
|
|
||||||
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_create_ip, &s_create_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
|
|
||||||
m_codecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
|
|
||||||
m_codecCtx->pv_fxns = (void*)&ih264d_api_function;
|
|
||||||
m_codecCtx->u4_size = sizeof(iv_obj_t);
|
|
||||||
|
|
||||||
SetDecoderCoreCount(1);
|
|
||||||
|
|
||||||
m_isBufferedMode = isBufferedMode;
|
|
||||||
|
|
||||||
UpdateParameters(false);
|
|
||||||
|
|
||||||
m_bufferedResults.clear();
|
|
||||||
m_numDecodedFrames = 0;
|
|
||||||
m_hasBufferSizeInfo = false;
|
|
||||||
m_timestampIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Destroy()
|
|
||||||
{
|
|
||||||
if (!m_codecCtx)
|
|
||||||
return;
|
|
||||||
ih264d_delete_ip_t s_delete_ip{ 0 };
|
|
||||||
ih264d_delete_op_t s_delete_op{ 0 };
|
|
||||||
s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ih264d_delete_ip_t);
|
|
||||||
s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
|
|
||||||
s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ih264d_delete_op_t);
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_delete_ip, &s_delete_op);
|
|
||||||
cemu_assert_debug(!status);
|
|
||||||
m_codecCtx = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetDecoderCoreCount(uint32 coreCount)
|
|
||||||
{
|
|
||||||
ih264d_ctl_set_num_cores_ip_t s_set_cores_ip;
|
|
||||||
ih264d_ctl_set_num_cores_op_t s_set_cores_op;
|
|
||||||
s_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
s_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES;
|
|
||||||
s_set_cores_ip.u4_num_cores = coreCount; // valid numbers are 1-4
|
|
||||||
s_set_cores_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t);
|
|
||||||
s_set_cores_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t);
|
|
||||||
IV_API_CALL_STATUS_T status = ih264d_api_function(m_codecCtx, (void *)&s_set_cores_ip, (void *)&s_set_cores_op);
|
|
||||||
cemu_assert(status == IV_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool GetImageInfo(uint8* stream, uint32 length, uint32& imageWidth, uint32& imageHeight)
|
|
||||||
{
|
|
||||||
// create temporary decoder
|
|
||||||
ih264d_create_ip_t s_create_ip{ 0 };
|
|
||||||
ih264d_create_op_t s_create_op{ 0 };
|
|
||||||
s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t);
|
|
||||||
s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
|
|
||||||
s_create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t);
|
|
||||||
s_create_ip.s_ivd_create_ip_t.e_output_format = IV_YUV_420SP_UV;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free;
|
|
||||||
s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
|
|
||||||
iv_obj_t* ctx = nullptr;
|
|
||||||
WORD32 status = ih264d_api_function(ctx, &s_create_ip, &s_create_op);
|
|
||||||
cemu_assert_debug(!status);
|
|
||||||
if (status != IV_SUCCESS)
|
|
||||||
return false;
|
|
||||||
ctx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle;
|
|
||||||
ctx->pv_fxns = (void*)&ih264d_api_function;
|
|
||||||
ctx->u4_size = sizeof(iv_obj_t);
|
|
||||||
// set header-only mode
|
|
||||||
ih264d_ctl_set_config_ip_t s_h264d_ctl_ip{ 0 };
|
|
||||||
ih264d_ctl_set_config_op_t s_h264d_ctl_op{ 0 };
|
|
||||||
ivd_ctl_set_config_ip_t* ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
|
|
||||||
ivd_ctl_set_config_op_t* ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
|
|
||||||
ps_ctl_ip->u4_disp_wd = 0;
|
|
||||||
ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
|
|
||||||
ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
|
|
||||||
ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER;
|
|
||||||
ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
|
|
||||||
ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t);
|
|
||||||
ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t);
|
|
||||||
status = ih264d_api_function(ctx, &s_h264d_ctl_ip, &s_h264d_ctl_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
// decode stream
|
|
||||||
ivd_video_decode_ip_t s_dec_ip{ 0 };
|
|
||||||
ivd_video_decode_op_t s_dec_op{ 0 };
|
|
||||||
s_dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
|
|
||||||
s_dec_op.u4_size = sizeof(ivd_video_decode_op_t);
|
|
||||||
s_dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
|
|
||||||
s_dec_ip.pv_stream_buffer = stream;
|
|
||||||
s_dec_ip.u4_num_Bytes = length;
|
|
||||||
s_dec_ip.s_out_buffer.u4_num_bufs = 0;
|
|
||||||
|
|
||||||
s_dec_op.u4_raw_wd = 0;
|
|
||||||
s_dec_op.u4_raw_ht = 0;
|
|
||||||
|
|
||||||
status = ih264d_api_function(ctx, &s_dec_ip, &s_dec_op);
|
|
||||||
//cemu_assert(status == 0); -> This errors when not both the headers are present, but it will still set the parameters we need
|
|
||||||
bool isValid = false;
|
|
||||||
if (true)//status == 0)
|
|
||||||
{
|
|
||||||
imageWidth = s_dec_op.u4_raw_wd;
|
|
||||||
imageHeight = s_dec_op.u4_raw_ht;
|
|
||||||
cemu_assert_debug(imageWidth != 0 && imageHeight != 0);
|
|
||||||
isValid = true;
|
|
||||||
}
|
|
||||||
// destroy decoder
|
|
||||||
ih264d_delete_ip_t s_delete_ip{ 0 };
|
|
||||||
ih264d_delete_op_t s_delete_op{ 0 };
|
|
||||||
s_delete_ip.s_ivd_delete_ip_t.u4_size = sizeof(ih264d_delete_ip_t);
|
|
||||||
s_delete_ip.s_ivd_delete_ip_t.e_cmd = IVD_CMD_DELETE;
|
|
||||||
s_delete_op.s_ivd_delete_op_t.u4_size = sizeof(ih264d_delete_op_t);
|
|
||||||
status = ih264d_api_function(ctx, &s_delete_ip, &s_delete_op);
|
|
||||||
cemu_assert_debug(!status);
|
|
||||||
return isValid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Decode(void* data, uint32 length, double timestamp, void* imageOutput, DecodeResult& decodeResult)
|
|
||||||
{
|
|
||||||
if (!m_hasBufferSizeInfo)
|
|
||||||
{
|
|
||||||
uint32 numByteConsumed = 0;
|
|
||||||
if (!DetermineBufferSizes(data, length, numByteConsumed))
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::Force, "H264: Unable to determine picture size. Ignoring decode input");
|
|
||||||
decodeResult.frameReady = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
length -= numByteConsumed;
|
|
||||||
data = (uint8*)data + numByteConsumed;
|
|
||||||
m_hasBufferSizeInfo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ivd_video_decode_ip_t s_dec_ip{ 0 };
|
|
||||||
ivd_video_decode_op_t s_dec_op{ 0 };
|
|
||||||
s_dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
|
|
||||||
s_dec_op.u4_size = sizeof(ivd_video_decode_op_t);
|
|
||||||
|
|
||||||
s_dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
|
|
||||||
|
|
||||||
// remember timestamp and associated output buffer
|
|
||||||
m_timestamps[m_timestampIndex] = timestamp;
|
|
||||||
m_imageBuffers[m_timestampIndex] = imageOutput;
|
|
||||||
s_dec_ip.u4_ts = m_timestampIndex;
|
|
||||||
m_timestampIndex = (m_timestampIndex + 1) % 64;
|
|
||||||
|
|
||||||
s_dec_ip.pv_stream_buffer = (uint8*)data;
|
|
||||||
s_dec_ip.u4_num_Bytes = length;
|
|
||||||
|
|
||||||
s_dec_ip.s_out_buffer.u4_min_out_buf_size[0] = 0;
|
|
||||||
s_dec_ip.s_out_buffer.u4_min_out_buf_size[1] = 0;
|
|
||||||
s_dec_ip.s_out_buffer.u4_num_bufs = 0;
|
|
||||||
|
|
||||||
BenchmarkTimer bt;
|
|
||||||
bt.Start();
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_dec_ip, &s_dec_op);
|
|
||||||
if (status != 0 && (s_dec_op.u4_error_code&0xFF) == IVD_RES_CHANGED)
|
|
||||||
{
|
|
||||||
// resolution change
|
|
||||||
ResetDecoder();
|
|
||||||
m_hasBufferSizeInfo = false;
|
|
||||||
Decode(data, length, timestamp, imageOutput, decodeResult);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (status != 0)
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::Force, "H264: Failed to decode frame (error 0x{:08x})", status);
|
|
||||||
decodeResult.frameReady = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bt.Stop();
|
|
||||||
double decodeTime = bt.GetElapsedMilliseconds();
|
|
||||||
|
|
||||||
cemu_assert(s_dec_op.u4_frame_decoded_flag);
|
|
||||||
cemu_assert_debug(s_dec_op.u4_num_bytes_consumed == length);
|
|
||||||
|
|
||||||
cemu_assert_debug(m_isBufferedMode || s_dec_op.u4_output_present); // if buffered mode is disabled, then every input should output a frame (except for partial slices?)
|
|
||||||
|
|
||||||
if (s_dec_op.u4_output_present)
|
|
||||||
{
|
|
||||||
cemu_assert(s_dec_op.e_output_format == IV_YUV_420SP_UV);
|
|
||||||
if (H264_IsBotW())
|
|
||||||
{
|
|
||||||
if (s_dec_op.s_disp_frm_buf.u4_y_wd == 1920 && s_dec_op.s_disp_frm_buf.u4_y_ht == 1088)
|
|
||||||
s_dec_op.s_disp_frm_buf.u4_y_ht = 1080;
|
|
||||||
}
|
|
||||||
DecodeResult tmpResult;
|
|
||||||
tmpResult.frameReady = s_dec_op.u4_output_present != 0;
|
|
||||||
tmpResult.timestamp = m_timestamps[s_dec_op.u4_ts];
|
|
||||||
tmpResult.imageOutput = m_imageBuffers[s_dec_op.u4_ts];
|
|
||||||
tmpResult.decodeOutput = s_dec_op;
|
|
||||||
AddBufferedResult(tmpResult);
|
|
||||||
// transfer image to PPC output buffer and also correct stride
|
|
||||||
bt.Start();
|
|
||||||
CopyImageToResultBuffer((uint8*)s_dec_op.s_disp_frm_buf.pv_y_buf, (uint8*)s_dec_op.s_disp_frm_buf.pv_u_buf, (uint8*)m_imageBuffers[s_dec_op.u4_ts], s_dec_op);
|
|
||||||
bt.Stop();
|
|
||||||
double copyTime = bt.GetElapsedMilliseconds();
|
|
||||||
// release buffer
|
|
||||||
sint32 bufferId = -1;
|
|
||||||
for (size_t i = 0; i < m_displayBuf.size(); i++)
|
|
||||||
{
|
|
||||||
if (s_dec_op.s_disp_frm_buf.pv_y_buf >= m_displayBuf[i].data() && s_dec_op.s_disp_frm_buf.pv_y_buf < (m_displayBuf[i].data() + m_displayBuf[i].size()))
|
|
||||||
{
|
|
||||||
bufferId = (sint32)i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cemu_assert_debug(bufferId == s_dec_op.u4_disp_buf_id);
|
|
||||||
cemu_assert(bufferId >= 0);
|
|
||||||
ivd_rel_display_frame_ip_t s_video_rel_disp_ip{ 0 };
|
|
||||||
ivd_rel_display_frame_op_t s_video_rel_disp_op{ 0 };
|
|
||||||
s_video_rel_disp_ip.e_cmd = IVD_CMD_REL_DISPLAY_FRAME;
|
|
||||||
s_video_rel_disp_ip.u4_size = sizeof(ivd_rel_display_frame_ip_t);
|
|
||||||
s_video_rel_disp_op.u4_size = sizeof(ivd_rel_display_frame_op_t);
|
|
||||||
s_video_rel_disp_ip.u4_disp_buf_id = bufferId;
|
|
||||||
status = ih264d_api_function(m_codecCtx, &s_video_rel_disp_ip, &s_video_rel_disp_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
|
|
||||||
cemuLog_log(LogType::H264, "H264Bench | DecodeTime {}ms CopyTime {}ms", decodeTime, copyTime);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::H264, "H264Bench | DecodeTime{}ms", decodeTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s_dec_op.u4_frame_decoded_flag)
|
|
||||||
m_numDecodedFrames++;
|
|
||||||
|
|
||||||
if (m_isBufferedMode)
|
|
||||||
{
|
|
||||||
// in buffered mode, always buffer 5 frames regardless of actual reordering and decoder latency
|
|
||||||
if (m_numDecodedFrames > 5)
|
|
||||||
GetCurrentBufferedResult(decodeResult);
|
|
||||||
}
|
|
||||||
else if(m_numDecodedFrames > 0)
|
|
||||||
GetCurrentBufferedResult(decodeResult);
|
|
||||||
|
|
||||||
// get VUI
|
|
||||||
//ih264d_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
|
|
||||||
//ih264d_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
|
|
||||||
|
|
||||||
//s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
//s_ctl_get_vui_params_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_GET_VUI_PARAMS;
|
|
||||||
//s_ctl_get_vui_params_ip.u4_size = sizeof(ih264d_ctl_get_vui_params_ip_t);
|
|
||||||
//s_ctl_get_vui_params_op.u4_size = sizeof(ih264d_ctl_get_vui_params_op_t);
|
|
||||||
|
|
||||||
//status = ih264d_api_function(mCodecCtx, &s_ctl_get_vui_params_ip, &s_ctl_get_vui_params_op);
|
|
||||||
//cemu_assert(status == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<DecodeResult> Flush()
|
|
||||||
{
|
|
||||||
std::vector<DecodeResult> results;
|
|
||||||
// set flush mode
|
|
||||||
ivd_ctl_flush_ip_t s_video_flush_ip{ 0 };
|
|
||||||
ivd_ctl_flush_op_t s_video_flush_op{ 0 };
|
|
||||||
s_video_flush_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
s_video_flush_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
|
|
||||||
s_video_flush_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
|
|
||||||
s_video_flush_op.u4_size = sizeof(ivd_ctl_flush_op_t);
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_video_flush_ip, &s_video_flush_op);
|
|
||||||
if (status != 0)
|
|
||||||
cemuLog_log(LogType::Force, "H264Dec: Unexpected error during flush ({})", status);
|
|
||||||
// get all frames from the codec
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
ivd_video_decode_ip_t s_dec_ip{ 0 };
|
|
||||||
ivd_video_decode_op_t s_dec_op{ 0 };
|
|
||||||
s_dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
|
|
||||||
s_dec_op.u4_size = sizeof(ivd_video_decode_op_t);
|
|
||||||
s_dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
|
|
||||||
s_dec_ip.pv_stream_buffer = NULL;
|
|
||||||
s_dec_ip.u4_num_Bytes = 0;
|
|
||||||
s_dec_ip.s_out_buffer.u4_min_out_buf_size[0] = 0;
|
|
||||||
s_dec_ip.s_out_buffer.u4_min_out_buf_size[1] = 0;
|
|
||||||
s_dec_ip.s_out_buffer.u4_num_bufs = 0;
|
|
||||||
status = ih264d_api_function(m_codecCtx, &s_dec_ip, &s_dec_op);
|
|
||||||
if (status != 0)
|
|
||||||
break;
|
|
||||||
cemu_assert_debug(s_dec_op.u4_output_present != 0); // should never be zero?
|
|
||||||
if(s_dec_op.u4_output_present == 0)
|
|
||||||
continue;
|
|
||||||
if (H264_IsBotW())
|
|
||||||
{
|
|
||||||
if (s_dec_op.s_disp_frm_buf.u4_y_wd == 1920 && s_dec_op.s_disp_frm_buf.u4_y_ht == 1088)
|
|
||||||
s_dec_op.s_disp_frm_buf.u4_y_ht = 1080;
|
|
||||||
}
|
|
||||||
DecodeResult tmpResult;
|
|
||||||
tmpResult.frameReady = s_dec_op.u4_output_present != 0;
|
|
||||||
tmpResult.timestamp = m_timestamps[s_dec_op.u4_ts];
|
|
||||||
tmpResult.imageOutput = m_imageBuffers[s_dec_op.u4_ts];
|
|
||||||
tmpResult.decodeOutput = s_dec_op;
|
|
||||||
AddBufferedResult(tmpResult);
|
|
||||||
CopyImageToResultBuffer((uint8*)s_dec_op.s_disp_frm_buf.pv_y_buf, (uint8*)s_dec_op.s_disp_frm_buf.pv_u_buf, (uint8*)m_imageBuffers[s_dec_op.u4_ts], s_dec_op);
|
|
||||||
}
|
|
||||||
results = std::move(m_bufferedResults);
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CopyImageToResultBuffer(uint8* yIn, uint8* uvIn, uint8* bufOut, ivd_video_decode_op_t& decodeInfo)
|
|
||||||
{
|
|
||||||
uint32 imageWidth = decodeInfo.s_disp_frm_buf.u4_y_wd;
|
|
||||||
uint32 imageHeight = decodeInfo.s_disp_frm_buf.u4_y_ht;
|
|
||||||
|
|
||||||
size_t inputStride = decodeInfo.s_disp_frm_buf.u4_y_strd;
|
|
||||||
size_t outputStride = (imageWidth + 0xFF) & ~0xFF;
|
|
||||||
|
|
||||||
// copy Y
|
|
||||||
uint8* yOut = bufOut;
|
|
||||||
for (uint32 row = 0; row < imageHeight; row++)
|
|
||||||
{
|
|
||||||
memcpy(yOut, yIn, imageWidth);
|
|
||||||
yIn += inputStride;
|
|
||||||
yOut += outputStride;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy UV
|
|
||||||
uint8* uvOut = bufOut + outputStride * imageHeight;
|
|
||||||
for (uint32 row = 0; row < imageHeight/2; row++)
|
|
||||||
{
|
|
||||||
memcpy(uvOut, uvIn, imageWidth);
|
|
||||||
uvIn += inputStride;
|
|
||||||
uvOut += outputStride;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
bool DetermineBufferSizes(void* data, uint32 length, uint32& numByteConsumed)
|
|
||||||
{
|
|
||||||
numByteConsumed = 0;
|
|
||||||
UpdateParameters(true);
|
|
||||||
|
|
||||||
ivd_video_decode_ip_t s_dec_ip{ 0 };
|
|
||||||
ivd_video_decode_op_t s_dec_op{ 0 };
|
|
||||||
s_dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
|
|
||||||
s_dec_op.u4_size = sizeof(ivd_video_decode_op_t);
|
|
||||||
|
|
||||||
s_dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
|
|
||||||
s_dec_ip.pv_stream_buffer = (uint8*)data;
|
|
||||||
s_dec_ip.u4_num_Bytes = length;
|
|
||||||
s_dec_ip.s_out_buffer.u4_num_bufs = 0;
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_dec_ip, &s_dec_op);
|
|
||||||
if (status != 0)
|
|
||||||
{
|
|
||||||
cemuLog_log(LogType::Force, "H264: Unable to determine buffer sizes for stream");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
numByteConsumed = s_dec_op.u4_num_bytes_consumed;
|
|
||||||
cemu_assert(status == 0);
|
|
||||||
if (s_dec_op.u4_pic_wd == 0 || s_dec_op.u4_pic_ht == 0)
|
|
||||||
return false;
|
|
||||||
UpdateParameters(false);
|
|
||||||
ReinitBuffers();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReinitBuffers()
|
|
||||||
{
|
|
||||||
ivd_ctl_getbufinfo_ip_t s_ctl_ip{ 0 };
|
|
||||||
ivd_ctl_getbufinfo_op_t s_ctl_op{ 0 };
|
|
||||||
WORD32 outlen = 0;
|
|
||||||
|
|
||||||
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
|
|
||||||
s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
|
|
||||||
s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
|
|
||||||
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_ctl_ip, &s_ctl_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
|
|
||||||
// allocate
|
|
||||||
for (uint32 i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
|
|
||||||
{
|
|
||||||
m_displayBuf.emplace_back().resize(s_ctl_op.u4_min_out_buf_size[0] + s_ctl_op.u4_min_out_buf_size[1]);
|
|
||||||
}
|
|
||||||
// set
|
|
||||||
ivd_set_display_frame_ip_t s_set_display_frame_ip{ 0 }; // make sure to zero-initialize this. The codec seems to check the first 3 pointers/sizes per frame, regardless of the value of u4_num_bufs
|
|
||||||
ivd_set_display_frame_op_t s_set_display_frame_op{ 0 };
|
|
||||||
|
|
||||||
s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME;
|
|
||||||
s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t);
|
|
||||||
s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t);
|
|
||||||
|
|
||||||
cemu_assert_debug(s_ctl_op.u4_min_num_out_bufs == 2);
|
|
||||||
cemu_assert_debug(s_ctl_op.u4_min_out_buf_size[0] != 0 && s_ctl_op.u4_min_out_buf_size[1] != 0);
|
|
||||||
|
|
||||||
s_set_display_frame_ip.num_disp_bufs = s_ctl_op.u4_num_disp_bufs;
|
|
||||||
|
|
||||||
for (uint32 i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
|
|
||||||
{
|
|
||||||
s_set_display_frame_ip.s_disp_buffer[i].u4_num_bufs = 2;
|
|
||||||
s_set_display_frame_ip.s_disp_buffer[i].u4_min_out_buf_size[0] = s_ctl_op.u4_min_out_buf_size[0];
|
|
||||||
s_set_display_frame_ip.s_disp_buffer[i].u4_min_out_buf_size[1] = s_ctl_op.u4_min_out_buf_size[1];
|
|
||||||
s_set_display_frame_ip.s_disp_buffer[i].pu1_bufs[0] = m_displayBuf[i].data() + 0;
|
|
||||||
s_set_display_frame_ip.s_disp_buffer[i].pu1_bufs[1] = m_displayBuf[i].data() + s_ctl_op.u4_min_out_buf_size[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ih264d_api_function(m_codecCtx, &s_set_display_frame_ip, &s_set_display_frame_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
|
|
||||||
|
|
||||||
// mark all as released (available)
|
|
||||||
for (uint32 i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
|
|
||||||
{
|
|
||||||
ivd_rel_display_frame_ip_t s_video_rel_disp_ip{ 0 };
|
|
||||||
ivd_rel_display_frame_op_t s_video_rel_disp_op{ 0 };
|
|
||||||
|
|
||||||
s_video_rel_disp_ip.e_cmd = IVD_CMD_REL_DISPLAY_FRAME;
|
|
||||||
s_video_rel_disp_ip.u4_size = sizeof(ivd_rel_display_frame_ip_t);
|
|
||||||
s_video_rel_disp_op.u4_size = sizeof(ivd_rel_display_frame_op_t);
|
|
||||||
s_video_rel_disp_ip.u4_disp_buf_id = i;
|
|
||||||
|
|
||||||
status = ih264d_api_function(m_codecCtx, &s_video_rel_disp_ip, &s_video_rel_disp_op);
|
|
||||||
cemu_assert(!status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ResetDecoder()
|
|
||||||
{
|
|
||||||
ivd_ctl_reset_ip_t s_ctl_ip;
|
|
||||||
ivd_ctl_reset_op_t s_ctl_op;
|
|
||||||
|
|
||||||
s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
|
|
||||||
s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
|
|
||||||
s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
|
|
||||||
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, (void*)&s_ctl_ip, (void*)&s_ctl_op);
|
|
||||||
cemu_assert_debug(status == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateParameters(bool headerDecodeOnly)
|
|
||||||
{
|
|
||||||
ih264d_ctl_set_config_ip_t s_h264d_ctl_ip{ 0 };
|
|
||||||
ih264d_ctl_set_config_op_t s_h264d_ctl_op{ 0 };
|
|
||||||
ivd_ctl_set_config_ip_t* ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
|
|
||||||
ivd_ctl_set_config_op_t* ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
|
|
||||||
|
|
||||||
ps_ctl_ip->u4_disp_wd = 0;
|
|
||||||
ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
|
|
||||||
ps_ctl_ip->e_frm_out_mode = m_isBufferedMode ? IVD_DISPLAY_FRAME_OUT : IVD_DECODE_FRAME_OUT;
|
|
||||||
ps_ctl_ip->e_vid_dec_mode = headerDecodeOnly ? IVD_DECODE_HEADER : IVD_DECODE_FRAME;
|
|
||||||
ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
|
|
||||||
ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
|
|
||||||
ps_ctl_ip->u4_size = sizeof(ih264d_ctl_set_config_ip_t);
|
|
||||||
ps_ctl_op->u4_size = sizeof(ih264d_ctl_set_config_op_t);
|
|
||||||
|
|
||||||
WORD32 status = ih264d_api_function(m_codecCtx, &s_h264d_ctl_ip, &s_h264d_ctl_op);
|
|
||||||
cemu_assert(status == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In non-flush mode we have a delay of (at least?) 5 frames */
|
|
||||||
void AddBufferedResult(DecodeResult& decodeResult)
|
|
||||||
{
|
|
||||||
if (decodeResult.frameReady)
|
|
||||||
m_bufferedResults.emplace_back(decodeResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetCurrentBufferedResult(DecodeResult& decodeResult)
|
|
||||||
{
|
|
||||||
cemu_assert(!m_bufferedResults.empty());
|
|
||||||
if (m_bufferedResults.empty())
|
|
||||||
{
|
|
||||||
decodeResult.frameReady = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
decodeResult = m_bufferedResults.front();
|
|
||||||
m_bufferedResults.erase(m_bufferedResults.begin());
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
iv_obj_t* m_codecCtx{nullptr};
|
|
||||||
bool m_hasBufferSizeInfo{ false };
|
|
||||||
bool m_isBufferedMode{ false };
|
|
||||||
double m_timestamps[64];
|
|
||||||
void* m_imageBuffers[64];
|
|
||||||
uint32 m_timestampIndex{0};
|
|
||||||
std::vector<DecodeResult> m_bufferedResults;
|
|
||||||
uint32 m_numDecodedFrames{0};
|
|
||||||
std::vector<std::vector<uint8>> m_displayBuf;
|
|
||||||
};
|
|
||||||
|
|
||||||
H264DEC_STATUS H264DECGetImageSize(uint8* stream, uint32 length, uint32 offset, uint32be* outputWidth, uint32be* outputHeight)
|
H264DEC_STATUS H264DECGetImageSize(uint8* stream, uint32 length, uint32 offset, uint32be* outputWidth, uint32be* outputHeight)
|
||||||
{
|
{
|
||||||
cemu_assert(offset <= length);
|
if(!stream || length < 4 || !outputWidth || !outputHeight)
|
||||||
|
return H264DEC_STATUS::INVALID_PARAM;
|
||||||
uint32 imageWidth, imageHeight;
|
if( (offset+4) > length )
|
||||||
|
return H264DEC_STATUS::INVALID_PARAM;
|
||||||
if (H264AVCDecoder::GetImageInfo(stream, length, imageWidth, imageHeight))
|
uint8* cur = stream + offset;
|
||||||
|
uint8* end = stream + length;
|
||||||
|
cur += 2; // we access cur[-2] and cur[-1] so we need to start at offset 2
|
||||||
|
while(cur < end-2)
|
||||||
{
|
{
|
||||||
if (H264_IsBotW())
|
// check for start code
|
||||||
|
if(*cur != 1)
|
||||||
{
|
{
|
||||||
if (imageWidth == 1920 && imageHeight == 1088)
|
cur++;
|
||||||
imageHeight = 1080;
|
continue;
|
||||||
}
|
}
|
||||||
*outputWidth = imageWidth;
|
// check if this is a valid NAL header
|
||||||
*outputHeight = imageHeight;
|
if(cur[-2] != 0 || cur[-1] != 0 || cur[0] != 1)
|
||||||
|
{
|
||||||
|
cur++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint8 nalHeader = cur[1];
|
||||||
|
if((nalHeader & 0x1F) != 7)
|
||||||
|
{
|
||||||
|
cur++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
h264State_seq_parameter_set_t psp;
|
||||||
|
bool r = h264Parser_ParseSPS(cur+2, end-cur-2, psp);
|
||||||
|
if(!r)
|
||||||
|
{
|
||||||
|
cemu_assert_suspicious(); // should not happen
|
||||||
|
return H264DEC_STATUS::BAD_STREAM;
|
||||||
|
}
|
||||||
|
*outputWidth = (psp.pic_width_in_mbs_minus1 + 1) * 16;
|
||||||
|
*outputHeight = (psp.pic_height_in_map_units_minus1 + 1) * 16; // affected by frame_mbs_only_flag?
|
||||||
|
return H264DEC_STATUS::SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
return H264DEC_STATUS::BAD_STREAM;
|
||||||
{
|
|
||||||
*outputWidth = 0;
|
|
||||||
*outputHeight = 0;
|
|
||||||
return H264DEC_STATUS::BAD_STREAM;
|
|
||||||
}
|
|
||||||
|
|
||||||
return H264DEC_STATUS::SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 H264DECInitParam(uint32 workMemorySize, void* workMemory)
|
uint32 H264DECInitParam(uint32 workMemorySize, void* workMemory)
|
||||||
@ -762,26 +239,28 @@ namespace H264
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<uint32, H264AVCDecoder*> sDecoderSessions;
|
std::unordered_map<uint32, H264DecoderBackend*> sDecoderSessions;
|
||||||
std::mutex sDecoderSessionsMutex;
|
std::mutex sDecoderSessionsMutex;
|
||||||
std::atomic_uint32_t sCurrentSessionHandle{ 1 };
|
std::atomic_uint32_t sCurrentSessionHandle{ 1 };
|
||||||
|
|
||||||
static H264AVCDecoder* _CreateDecoderSession(uint32& handleOut)
|
H264DecoderBackend* CreateAVCDecoder();
|
||||||
|
|
||||||
|
static H264DecoderBackend* _CreateDecoderSession(uint32& handleOut)
|
||||||
{
|
{
|
||||||
std::unique_lock _lock(sDecoderSessionsMutex);
|
std::unique_lock _lock(sDecoderSessionsMutex);
|
||||||
handleOut = sCurrentSessionHandle.fetch_add(1);
|
handleOut = sCurrentSessionHandle.fetch_add(1);
|
||||||
H264AVCDecoder* session = new H264AVCDecoder();
|
H264DecoderBackend* session = CreateAVCDecoder();
|
||||||
sDecoderSessions.try_emplace(handleOut, session);
|
sDecoderSessions.try_emplace(handleOut, session);
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
static H264AVCDecoder* _AcquireDecoderSession(uint32 handle)
|
static H264DecoderBackend* _AcquireDecoderSession(uint32 handle)
|
||||||
{
|
{
|
||||||
std::unique_lock _lock(sDecoderSessionsMutex);
|
std::unique_lock _lock(sDecoderSessionsMutex);
|
||||||
auto it = sDecoderSessions.find(handle);
|
auto it = sDecoderSessions.find(handle);
|
||||||
if (it == sDecoderSessions.end())
|
if (it == sDecoderSessions.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
H264AVCDecoder* session = it->second;
|
H264DecoderBackend* session = it->second;
|
||||||
if (sDecoderSessions.size() >= 5)
|
if (sDecoderSessions.size() >= 5)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "H264: Warning - more than 5 active sessions");
|
cemuLog_log(LogType::Force, "H264: Warning - more than 5 active sessions");
|
||||||
@ -790,7 +269,7 @@ namespace H264
|
|||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ReleaseDecoderSession(H264AVCDecoder* session)
|
static void _ReleaseDecoderSession(H264DecoderBackend* session)
|
||||||
{
|
{
|
||||||
std::unique_lock _lock(sDecoderSessionsMutex);
|
std::unique_lock _lock(sDecoderSessionsMutex);
|
||||||
|
|
||||||
@ -802,7 +281,7 @@ namespace H264
|
|||||||
auto it = sDecoderSessions.find(handle);
|
auto it = sDecoderSessions.find(handle);
|
||||||
if (it == sDecoderSessions.end())
|
if (it == sDecoderSessions.end())
|
||||||
return;
|
return;
|
||||||
H264AVCDecoder* session = it->second;
|
H264DecoderBackend* session = it->second;
|
||||||
session->Destroy();
|
session->Destroy();
|
||||||
delete session;
|
delete session;
|
||||||
sDecoderSessions.erase(it);
|
sDecoderSessions.erase(it);
|
||||||
@ -830,45 +309,44 @@ namespace H264
|
|||||||
uint32 H264DECBegin(void* workMemory)
|
uint32 H264DECBegin(void* workMemory)
|
||||||
{
|
{
|
||||||
H264Context* ctx = (H264Context*)workMemory;
|
H264Context* ctx = (H264Context*)workMemory;
|
||||||
H264AVCDecoder* session = _AcquireDecoderSession(ctx->sessionHandle);
|
H264DecoderBackend* session = _AcquireDecoderSession(ctx->sessionHandle);
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "H264DECBegin(): Invalid session");
|
cemuLog_log(LogType::Force, "H264DECBegin(): Invalid session");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
session->Init(ctx->Param.outputPerFrame == 0);
|
session->Init(ctx->Param.outputPerFrame == 0);
|
||||||
|
ctx->decoderState.numFramesInFlight = 0;
|
||||||
_ReleaseDecoderSession(session);
|
_ReleaseDecoderSession(session);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264DoFrameOutputCallback(H264Context* ctx, H264AVCDecoder::DecodeResult& decodeResult);
|
void H264DoFrameOutputCallback(H264Context* ctx, H264DecoderBackend::DecodeResult& decodeResult);
|
||||||
|
|
||||||
void _async_H264DECEnd(coreinit::OSEvent* executeDoneEvent, H264AVCDecoder* session, H264Context* ctx, std::vector<H264AVCDecoder::DecodeResult>* decodeResultsOut)
|
|
||||||
{
|
|
||||||
*decodeResultsOut = session->Flush();
|
|
||||||
coreinit::OSSignalEvent(executeDoneEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
H264DEC_STATUS H264DECEnd(void* workMemory)
|
H264DEC_STATUS H264DECEnd(void* workMemory)
|
||||||
{
|
{
|
||||||
H264Context* ctx = (H264Context*)workMemory;
|
H264Context* ctx = (H264Context*)workMemory;
|
||||||
H264AVCDecoder* session = _AcquireDecoderSession(ctx->sessionHandle);
|
H264DecoderBackend* session = _AcquireDecoderSession(ctx->sessionHandle);
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "H264DECEnd(): Invalid session");
|
cemuLog_log(LogType::Force, "H264DECEnd(): Invalid session");
|
||||||
return H264DEC_STATUS::SUCCESS;
|
return H264DEC_STATUS::SUCCESS;
|
||||||
}
|
}
|
||||||
StackAllocator<coreinit::OSEvent> executeDoneEvent;
|
coreinit::OSEvent* flushEvt = &session->GetFlushEvent();
|
||||||
coreinit::OSInitEvent(&executeDoneEvent, coreinit::OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, coreinit::OSEvent::EVENT_MODE::MODE_MANUAL);
|
coreinit::OSResetEvent(flushEvt);
|
||||||
std::vector<H264AVCDecoder::DecodeResult> results;
|
session->QueueFlush();
|
||||||
auto asyncTask = std::async(std::launch::async, _async_H264DECEnd, executeDoneEvent.GetPointer(), session, ctx, &results);
|
coreinit::OSWaitEvent(flushEvt);
|
||||||
coreinit::OSWaitEvent(&executeDoneEvent);
|
while(true)
|
||||||
_ReleaseDecoderSession(session);
|
|
||||||
if (!results.empty())
|
|
||||||
{
|
{
|
||||||
for (auto& itr : results)
|
H264DecoderBackend::DecodeResult decodeResult;
|
||||||
H264DoFrameOutputCallback(ctx, itr);
|
if( !session->GetFrameOutputIfReady(decodeResult) )
|
||||||
|
break;
|
||||||
|
// todo - output all frames in a single callback?
|
||||||
|
H264DoFrameOutputCallback(ctx, decodeResult);
|
||||||
|
ctx->decoderState.numFramesInFlight--;
|
||||||
}
|
}
|
||||||
|
cemu_assert_debug(ctx->decoderState.numFramesInFlight == 0); // no frames should be in flight anymore. Exact behavior is not well understood but we may have to output dummy frames if necessary
|
||||||
|
_ReleaseDecoderSession(session);
|
||||||
return H264DEC_STATUS::SUCCESS;
|
return H264DEC_STATUS::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,7 +408,6 @@ namespace H264
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct H264DECFrameOutput
|
struct H264DECFrameOutput
|
||||||
{
|
{
|
||||||
/* +0x00 */ uint32be result;
|
/* +0x00 */ uint32be result;
|
||||||
@ -967,7 +444,7 @@ namespace H264
|
|||||||
|
|
||||||
static_assert(sizeof(H264OutputCBStruct) == 12);
|
static_assert(sizeof(H264OutputCBStruct) == 12);
|
||||||
|
|
||||||
void H264DoFrameOutputCallback(H264Context* ctx, H264AVCDecoder::DecodeResult& decodeResult)
|
void H264DoFrameOutputCallback(H264Context* ctx, H264DecoderBackend::DecodeResult& decodeResult)
|
||||||
{
|
{
|
||||||
sint32 outputFrameCount = 1;
|
sint32 outputFrameCount = 1;
|
||||||
|
|
||||||
@ -984,14 +461,14 @@ namespace H264
|
|||||||
frameOutput->imagePtr = (uint8*)decodeResult.imageOutput;
|
frameOutput->imagePtr = (uint8*)decodeResult.imageOutput;
|
||||||
frameOutput->result = 100;
|
frameOutput->result = 100;
|
||||||
frameOutput->timestamp = decodeResult.timestamp;
|
frameOutput->timestamp = decodeResult.timestamp;
|
||||||
frameOutput->frameWidth = decodeResult.decodeOutput.u4_pic_wd;
|
frameOutput->frameWidth = decodeResult.frameWidth;
|
||||||
frameOutput->frameHeight = decodeResult.decodeOutput.u4_pic_ht;
|
frameOutput->frameHeight = decodeResult.frameHeight;
|
||||||
frameOutput->bytesPerRow = (decodeResult.decodeOutput.u4_pic_wd + 0xFF) & ~0xFF;
|
frameOutput->bytesPerRow = decodeResult.bytesPerRow;
|
||||||
frameOutput->cropEnable = decodeResult.decodeOutput.u1_frame_cropping_flag;
|
frameOutput->cropEnable = decodeResult.cropEnable;
|
||||||
frameOutput->cropTop = decodeResult.decodeOutput.u1_frame_cropping_rect_top_ofst;
|
frameOutput->cropTop = decodeResult.cropTop;
|
||||||
frameOutput->cropBottom = decodeResult.decodeOutput.u1_frame_cropping_rect_bottom_ofst;
|
frameOutput->cropBottom = decodeResult.cropBottom;
|
||||||
frameOutput->cropLeft = decodeResult.decodeOutput.u1_frame_cropping_rect_left_ofst;
|
frameOutput->cropLeft = decodeResult.cropLeft;
|
||||||
frameOutput->cropRight = decodeResult.decodeOutput.u1_frame_cropping_rect_right_ofst;
|
frameOutput->cropRight = decodeResult.cropRight;
|
||||||
|
|
||||||
StackAllocator<H264OutputCBStruct> stack_fptrOutputData;
|
StackAllocator<H264OutputCBStruct> stack_fptrOutputData;
|
||||||
stack_fptrOutputData->frameCount = outputFrameCount;
|
stack_fptrOutputData->frameCount = outputFrameCount;
|
||||||
@ -1006,29 +483,41 @@ namespace H264
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _async_H264DECExecute(coreinit::OSEvent* executeDoneEvent, H264AVCDecoder* session, H264Context* ctx, void* imageOutput, H264AVCDecoder::DecodeResult* decodeResult)
|
|
||||||
{
|
|
||||||
session->Decode(ctx->BitStream.ptr.GetPtr(), ctx->BitStream.length, ctx->BitStream.timestamp, imageOutput, *decodeResult);
|
|
||||||
coreinit::OSSignalEvent(executeDoneEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 H264DECExecute(void* workMemory, void* imageOutput)
|
uint32 H264DECExecute(void* workMemory, void* imageOutput)
|
||||||
{
|
{
|
||||||
|
BenchmarkTimer bt;
|
||||||
|
bt.Start();
|
||||||
H264Context* ctx = (H264Context*)workMemory;
|
H264Context* ctx = (H264Context*)workMemory;
|
||||||
H264AVCDecoder* session = _AcquireDecoderSession(ctx->sessionHandle);
|
H264DecoderBackend* session = _AcquireDecoderSession(ctx->sessionHandle);
|
||||||
if (!session)
|
if (!session)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "H264DECExecute(): Invalid session");
|
cemuLog_log(LogType::Force, "H264DECExecute(): Invalid session");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
StackAllocator<coreinit::OSEvent> executeDoneEvent;
|
// feed data to backend
|
||||||
coreinit::OSInitEvent(&executeDoneEvent, coreinit::OSEvent::EVENT_STATE::STATE_NOT_SIGNALED, coreinit::OSEvent::EVENT_MODE::MODE_MANUAL);
|
session->QueueForDecode((uint8*)ctx->BitStream.ptr.GetPtr(), ctx->BitStream.length, ctx->BitStream.timestamp, imageOutput);
|
||||||
H264AVCDecoder::DecodeResult decodeResult;
|
ctx->decoderState.numFramesInFlight++;
|
||||||
auto asyncTask = std::async(std::launch::async, _async_H264DECExecute, &executeDoneEvent, session, ctx, imageOutput , &decodeResult);
|
// H264DECExecute is synchronous and will return a frame after either every call (non-buffered) or after 6 calls (buffered)
|
||||||
coreinit::OSWaitEvent(&executeDoneEvent);
|
// normally frame decoding happens only during H264DECExecute, but in order to hide the latency of our CPU decoder we will decode asynchronously in buffered mode
|
||||||
|
uint32 numFramesToBuffer = (ctx->Param.outputPerFrame == 0) ? 5 : 0;
|
||||||
|
if(ctx->decoderState.numFramesInFlight > numFramesToBuffer)
|
||||||
|
{
|
||||||
|
ctx->decoderState.numFramesInFlight--;
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
coreinit::OSEvent& evt = session->GetFrameOutputEvent();
|
||||||
|
coreinit::OSWaitEvent(&evt);
|
||||||
|
H264DecoderBackend::DecodeResult decodeResult;
|
||||||
|
if( !session->GetFrameOutputIfReady(decodeResult) )
|
||||||
|
continue;
|
||||||
|
H264DoFrameOutputCallback(ctx, decodeResult);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
_ReleaseDecoderSession(session);
|
_ReleaseDecoderSession(session);
|
||||||
if(decodeResult.frameReady)
|
bt.Stop();
|
||||||
H264DoFrameOutputCallback(ctx, decodeResult);
|
double callTime = bt.GetElapsedMilliseconds();
|
||||||
|
cemuLog_log(LogType::H264, "H264Bench | H264DECExecute took {}ms", callTime);
|
||||||
return 0x80 | 100;
|
return 0x80 | 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user