mirror of
https://github.com/citra-emu/citra-nightly.git
synced 2025-09-28 23:17:04 +00:00
Compare commits
No commits in common. "master" and "nightly-1935" have entirely different histories.
master
...
nightly-19
|
@ -15,7 +15,7 @@ chmod +x ./gradlew
|
||||||
./gradlew assemble${BUILD_FLAVOR}Release
|
./gradlew assemble${BUILD_FLAVOR}Release
|
||||||
./gradlew bundle${BUILD_FLAVOR}Release
|
./gradlew bundle${BUILD_FLAVOR}Release
|
||||||
|
|
||||||
ccache -s -v
|
ccache -s
|
||||||
|
|
||||||
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
|
||||||
rm "${ANDROID_KEYSTORE_FILE}"
|
rm "${ANDROID_KEYSTORE_FILE}"
|
||||||
|
|
|
@ -7,7 +7,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Default clang-format points to default 3.5 version one
|
# Default clang-format points to default 3.5 version one
|
||||||
CLANG_FORMAT=clang-format-15
|
CLANG_FORMAT=clang-format-12
|
||||||
$CLANG_FORMAT --version
|
$CLANG_FORMAT --version
|
||||||
|
|
||||||
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
||||||
|
|
15
.ci/ios.sh
15
.ci/ios.sh
|
@ -1,15 +0,0 @@
|
||||||
#!/bin/bash -ex
|
|
||||||
|
|
||||||
mkdir build && cd build
|
|
||||||
cmake .. -GNinja \
|
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
|
||||||
-DCMAKE_SYSTEM_NAME=iOS \
|
|
||||||
-DCMAKE_OSX_ARCHITECTURES=arm64 \
|
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
|
||||||
ninja
|
|
||||||
|
|
||||||
ccache -s -v
|
|
17
.ci/linux.sh
17
.ci/linux.sh
|
@ -1,19 +1,10 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/sh -ex
|
||||||
|
|
||||||
if [ "$TARGET" = "appimage" ]; then
|
|
||||||
# Compile the AppImage we distribute with Clang.
|
|
||||||
export EXTRA_CMAKE_FLAGS=(-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_LINKER=/etc/bin/ld.lld)
|
|
||||||
else
|
|
||||||
# For the linux-fresh verification target, verify compilation without PCH as well.
|
|
||||||
export EXTRA_CMAKE_FLAGS=(-DCITRA_USE_PRECOMPILED_HEADERS=OFF)
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -G Ninja \
|
cmake .. -G Ninja \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
"${EXTRA_CMAKE_FLAGS[@]}" \
|
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
|
@ -22,10 +13,8 @@ ninja
|
||||||
|
|
||||||
if [ "$TARGET" = "appimage" ]; then
|
if [ "$TARGET" = "appimage" ]; then
|
||||||
ninja bundle
|
ninja bundle
|
||||||
# TODO: Our AppImage environment currently uses an older ccache version without the verbose flag.
|
|
||||||
ccache -s
|
|
||||||
else
|
|
||||||
ccache -s -v
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
ccache -s
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
# TODO: LibreSSL ASM disabled due to platform detection issues in cross-compile build.
|
||||||
cmake .. -GNinja \
|
cmake .. -GNinja \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
-DCMAKE_OSX_ARCHITECTURES="$TARGET" \
|
-DCMAKE_OSX_ARCHITECTURES="$TARGET" \
|
||||||
|
-DCMAKE_OSX_DEPLOYMENT_TARGET="11.0" \
|
||||||
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
|
||||||
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
|
||||||
-DENABLE_QT_TRANSLATION=ON \
|
-DENABLE_QT_TRANSLATION=ON \
|
||||||
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
|
||||||
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
|
||||||
-DUSE_DISCORD_PRESENCE=ON
|
-DUSE_DISCORD_PRESENCE=ON \
|
||||||
|
-DENABLE_ASM=OFF
|
||||||
ninja
|
ninja
|
||||||
ninja bundle
|
ninja bundle
|
||||||
|
|
||||||
ccache -s -v
|
ccache -s
|
||||||
|
|
||||||
CURRENT_ARCH=`arch`
|
CURRENT_ARCH=`arch`
|
||||||
if [ "$TARGET" = "$CURRENT_ARCH" ]; then
|
if [ "$TARGET" = "$CURRENT_ARCH" ]; then
|
||||||
|
|
78
.ci/pack.sh
78
.ci/pack.sh
|
@ -1,80 +1,48 @@
|
||||||
#!/bin/bash -ex
|
#!/bin/bash -ex
|
||||||
|
|
||||||
# Determine the full revision name.
|
|
||||||
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
|
||||||
GITREV="`git show -s --format='%h'`"
|
GITREV="`git show -s --format='%h'`"
|
||||||
REV_NAME="citra-$OS-$TARGET-$GITDATE-$GITREV"
|
REV_NAME="citra-${OS}-${TARGET}-${GITDATE}-${GITREV}"
|
||||||
|
|
||||||
# Determine the name of the release being built.
|
# Find out what release we are building
|
||||||
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
|
||||||
RELEASE_NAME=$(echo $GITHUB_REF_NAME | cut -d- -f1)
|
RELEASE_NAME=$(echo $GITHUB_REF_NAME | cut -d- -f1)
|
||||||
|
# For compatibility with existing installs, use mingw/osx in the archive and target names.
|
||||||
|
if [ "$TARGET" = "msys2" ]; then
|
||||||
|
REV_NAME="citra-${OS}-mingw-${GITDATE}-${GITREV}"
|
||||||
|
RELEASE_NAME="${RELEASE_NAME}-mingw"
|
||||||
|
elif [ "$OS" = "macos" ]; then
|
||||||
|
REV_NAME="citra-osx-${TARGET}-${GITDATE}-${GITREV}"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
RELEASE_NAME=head
|
RELEASE_NAME=head
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Archive and upload the artifacts.
|
mkdir -p artifacts
|
||||||
mkdir artifacts
|
|
||||||
|
|
||||||
function pack_artifacts() {
|
if [ -z "${UPLOAD_RAW}" ]; then
|
||||||
ARTIFACTS_PATH="$1"
|
# Archive and upload the artifacts.
|
||||||
|
|
||||||
# Set up root directory for archive.
|
|
||||||
mkdir "$REV_NAME"
|
mkdir "$REV_NAME"
|
||||||
if [ -f "$ARTIFACTS_PATH" ]; then
|
mv build/bundle/* "$REV_NAME"
|
||||||
mv "$ARTIFACTS_PATH" "$REV_NAME"
|
|
||||||
|
|
||||||
# Use file extension to differentiate archives.
|
|
||||||
FILENAME=$(basename "$ARTIFACT")
|
|
||||||
EXTENSION="${FILENAME##*.}"
|
|
||||||
ARCHIVE_NAME="$REV_NAME.$EXTENSION"
|
|
||||||
else
|
|
||||||
mv "$ARTIFACTS_PATH"/* "$REV_NAME"
|
|
||||||
|
|
||||||
ARCHIVE_NAME="$REV_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create .zip/.tar.gz
|
|
||||||
if [ "$OS" = "windows" ]; then
|
if [ "$OS" = "windows" ]; then
|
||||||
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
|
ARCHIVE_NAME="${REV_NAME}.zip"
|
||||||
powershell Compress-Archive "$REV_NAME" "$ARCHIVE_FULL_NAME"
|
powershell Compress-Archive "$REV_NAME" "$ARCHIVE_NAME"
|
||||||
elif [ "$OS" = "android" ]; then
|
|
||||||
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
|
|
||||||
zip -r "$ARCHIVE_FULL_NAME" "$REV_NAME"
|
|
||||||
else
|
else
|
||||||
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.tar.gz"
|
ARCHIVE_NAME="${REV_NAME}.tar.gz"
|
||||||
tar czvf "$ARCHIVE_FULL_NAME" "$REV_NAME"
|
tar czvf "$ARCHIVE_NAME" "$REV_NAME"
|
||||||
fi
|
fi
|
||||||
mv "$ARCHIVE_FULL_NAME" artifacts/
|
|
||||||
|
|
||||||
if [ -z "$SKIP_7Z" ]; then
|
mv "$REV_NAME" $RELEASE_NAME
|
||||||
# Create .7z
|
7z a "$REV_NAME.7z" $RELEASE_NAME
|
||||||
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.7z"
|
|
||||||
mv "$REV_NAME" "$RELEASE_NAME"
|
|
||||||
7z a "$ARCHIVE_FULL_NAME" "$RELEASE_NAME"
|
|
||||||
mv "$ARCHIVE_FULL_NAME" artifacts/
|
|
||||||
|
|
||||||
# Clean up created release artifacts directory.
|
mv "$ARCHIVE_NAME" artifacts/
|
||||||
rm -rf "$RELEASE_NAME"
|
mv "$REV_NAME.7z" artifacts/
|
||||||
else
|
else
|
||||||
# Clean up created rev artifacts directory.
|
# Directly upload the raw artifacts, renamed with the revision.
|
||||||
rm -rf "$REV_NAME"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
if [ -n "$UNPACKED" ]; then
|
|
||||||
# Copy the artifacts to be uploaded unpacked.
|
|
||||||
for ARTIFACT in build/bundle/*; do
|
for ARTIFACT in build/bundle/*; do
|
||||||
FILENAME=$(basename "$ARTIFACT")
|
FILENAME=$(basename "$ARTIFACT")
|
||||||
EXTENSION="${FILENAME##*.}"
|
EXTENSION="${FILENAME##*.}"
|
||||||
|
|
||||||
mv "$ARTIFACT" "artifacts/$REV_NAME.$EXTENSION"
|
mv "$ARTIFACT" "artifacts/$REV_NAME.$EXTENSION"
|
||||||
done
|
done
|
||||||
elif [ -n "$PACK_INDIVIDUALLY" ]; then
|
|
||||||
# Pack and upload the artifacts one-by-one.
|
|
||||||
for ARTIFACT in build/bundle/*; do
|
|
||||||
pack_artifacts "$ARTIFACT"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
# Pack all of the artifacts into a single archive.
|
|
||||||
pack_artifacts build/bundle
|
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -12,6 +12,6 @@ cmake .. -G Ninja \
|
||||||
ninja
|
ninja
|
||||||
ninja bundle
|
ninja bundle
|
||||||
|
|
||||||
ccache -s -v
|
ccache -s
|
||||||
|
|
||||||
ctest -VV -C Release || echo "::error ::Test error occurred on Windows build"
|
ctest -VV -C Release || echo "::error ::Test error occurred on Windows build"
|
||||||
|
|
8
.github/workflows/ci-merge.js
vendored
8
.github/workflows/ci-merge.js
vendored
|
@ -11,7 +11,7 @@ async function checkBaseChanges(github, context) {
|
||||||
repository(name:$name, owner:$owner) {
|
repository(name:$name, owner:$owner) {
|
||||||
ref(qualifiedName:$ref) {
|
ref(qualifiedName:$ref) {
|
||||||
target {
|
target {
|
||||||
... on Commit { id committedDate oid }
|
... on Commit { id pushedDate oid }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ async function checkBaseChanges(github, context) {
|
||||||
ref: 'refs/heads/master',
|
ref: 'refs/heads/master',
|
||||||
};
|
};
|
||||||
const result = await github.graphql(query, variables);
|
const result = await github.graphql(query, variables);
|
||||||
const committedAt = result.repository.ref.target.committedDate;
|
const pushedAt = result.repository.ref.target.pushedDate;
|
||||||
console.log(`Last commit committed at ${committedAt}.`);
|
console.log(`Last commit pushed at ${pushedAt}.`);
|
||||||
const delta = new Date() - new Date(committedAt);
|
const delta = new Date() - new Date(pushedAt);
|
||||||
if (delta <= DETECTION_TIME_FRAME) {
|
if (delta <= DETECTION_TIME_FRAME) {
|
||||||
console.info('New changes detected, triggering a new build.');
|
console.info('New changes detected, triggering a new build.');
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name: citra-build
|
name: citra-ci
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
@ -8,17 +8,30 @@ on:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
clang-format:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: citraemu/build-environments:linux-fresh
|
||||||
|
options: -u 1001
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Build
|
||||||
|
env:
|
||||||
|
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
||||||
|
run: ./.ci/clang-format.sh
|
||||||
source:
|
source:
|
||||||
if: ${{ !github.head_ref }}
|
if: ${{ !github.head_ref }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Pack
|
- name: Pack
|
||||||
run: ./.ci/source.sh
|
run: ./.ci/source.sh
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: source
|
name: source
|
||||||
path: artifacts/
|
path: artifacts/
|
||||||
|
@ -32,16 +45,14 @@ jobs:
|
||||||
options: -u 1001
|
options: -u 1001
|
||||||
env:
|
env:
|
||||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
CCACHE_COMPILERCHECK: content
|
|
||||||
CCACHE_SLOPPINESS: time_macros
|
|
||||||
OS: linux
|
OS: linux
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Set up cache
|
- name: Set up cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.CCACHE_DIR }}
|
path: ${{ env.CCACHE_DIR }}
|
||||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
|
@ -53,60 +64,62 @@ jobs:
|
||||||
run: ./.ci/pack.sh
|
run: ./.ci/pack.sh
|
||||||
if: ${{ matrix.target == 'appimage' }}
|
if: ${{ matrix.target == 'appimage' }}
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
if: ${{ matrix.target == 'appimage' }}
|
if: ${{ matrix.target == 'appimage' }}
|
||||||
with:
|
with:
|
||||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
path: artifacts/
|
path: artifacts/
|
||||||
macos:
|
macos:
|
||||||
runs-on: ${{ (matrix.target == 'x86_64' && 'macos-13') || 'macos-14' }}
|
runs-on: macos-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
target: ["x86_64", "arm64"]
|
target: ["x86_64", "arm64"]
|
||||||
env:
|
env:
|
||||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
CCACHE_CPP2: yes
|
||||||
CCACHE_COMPILERCHECK: content
|
|
||||||
CCACHE_SLOPPINESS: time_macros
|
CCACHE_SLOPPINESS: time_macros
|
||||||
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
OS: macos
|
OS: macos
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Set up cache
|
- name: Set up cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.CCACHE_DIR }}
|
path: ${{ env.CCACHE_DIR }}
|
||||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-${{ matrix.target }}-
|
${{ runner.os }}-${{ matrix.target }}-
|
||||||
- name: Install tools
|
- name: Install tools
|
||||||
run: brew install ccache ninja
|
run: brew install ccache glslang ninja
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/macos.sh
|
run: ./.ci/macos.sh
|
||||||
- name: Prepare outputs for caching
|
- name: Prepare outputs for caching
|
||||||
run: mv build/bundle $OS-$TARGET
|
run: mv build/bundle $OS-$TARGET
|
||||||
- name: Cache outputs for universal build
|
- name: Cache outputs for universal build
|
||||||
uses: actions/cache/save@v4
|
uses: actions/cache/save@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.OS }}-${{ env.TARGET }}
|
path: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
macos-universal:
|
macos-universal:
|
||||||
runs-on: macos-14
|
runs-on: macos-latest
|
||||||
needs: macos
|
needs: macos
|
||||||
env:
|
env:
|
||||||
OS: macos
|
OS: macos
|
||||||
TARGET: universal
|
TARGET: universal
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
- name: Download x86_64 build from cache
|
- name: Download x86_64 build from cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.OS }}-x86_64
|
path: ${{ env.OS }}-x86_64
|
||||||
key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
key: ${{ runner.os }}-x86_64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
fail-on-cache-miss: true
|
fail-on-cache-miss: true
|
||||||
- name: Download ARM64 build from cache
|
- name: Download ARM64 build from cache
|
||||||
uses: actions/cache/restore@v4
|
uses: actions/cache/restore@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.OS }}-arm64
|
path: ${{ env.OS }}-arm64
|
||||||
key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
key: ${{ runner.os }}-arm64-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}
|
||||||
|
@ -117,11 +130,11 @@ jobs:
|
||||||
ARTIFACTS: ${{ env.OS }}-x86_64 ${{ env.OS }}-arm64
|
ARTIFACTS: ${{ env.OS }}-x86_64 ${{ env.OS }}-arm64
|
||||||
- name: Pack
|
- name: Pack
|
||||||
run: ./.ci/pack.sh
|
run: ./.ci/pack.sh
|
||||||
- name: Upload
|
# - name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
# uses: actions/upload-artifact@v3
|
||||||
with:
|
# with:
|
||||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
# name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
path: artifacts/
|
# path: artifacts/
|
||||||
windows:
|
windows:
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
strategy:
|
strategy:
|
||||||
|
@ -132,16 +145,14 @@ jobs:
|
||||||
shell: ${{ (matrix.target == 'msys2' && 'msys2') || 'bash' }} {0}
|
shell: ${{ (matrix.target == 'msys2' && 'msys2') || 'bash' }} {0}
|
||||||
env:
|
env:
|
||||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||||
CCACHE_COMPILERCHECK: content
|
|
||||||
CCACHE_SLOPPINESS: time_macros
|
|
||||||
OS: windows
|
OS: windows
|
||||||
TARGET: ${{ matrix.target }}
|
TARGET: ${{ matrix.target }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Set up cache
|
- name: Set up cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ env.CCACHE_DIR }}
|
path: ${{ env.CCACHE_DIR }}
|
||||||
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
key: ${{ runner.os }}-${{ matrix.target }}-${{ github.sha }}
|
||||||
|
@ -150,7 +161,7 @@ jobs:
|
||||||
- name: Set up MSVC
|
- name: Set up MSVC
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
if: ${{ matrix.target == 'msvc' }}
|
if: ${{ matrix.target == 'msvc' }}
|
||||||
- name: Install extra tools (MSVC)
|
- name: Install MSVC extra tools
|
||||||
run: choco install ccache ninja wget
|
run: choco install ccache ninja wget
|
||||||
if: ${{ matrix.target == 'msvc' }}
|
if: ${{ matrix.target == 'msvc' }}
|
||||||
- name: Set up MSYS2
|
- name: Set up MSYS2
|
||||||
|
@ -162,37 +173,40 @@ jobs:
|
||||||
install: git make p7zip
|
install: git make p7zip
|
||||||
pacboy: >-
|
pacboy: >-
|
||||||
toolchain:p ccache:p cmake:p ninja:p
|
toolchain:p ccache:p cmake:p ninja:p
|
||||||
qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p qt6-translations:p
|
qt6-base:p qt6-multimedia:p qt6-multimedia-wmf:p qt6-tools:p
|
||||||
- name: Disable line ending translation
|
- name: Setup Vulkan SDK
|
||||||
run: git config --global core.autocrlf input
|
uses: humbletim/setup-vulkan-sdk@v1.2.0
|
||||||
|
with:
|
||||||
|
vulkan-query-version: latest
|
||||||
|
vulkan-components: Glslang
|
||||||
|
vulkan-use-cache: true
|
||||||
|
- name: Test glslangValidator
|
||||||
|
run: glslangValidator --version
|
||||||
- name: Build
|
- name: Build
|
||||||
run: ./.ci/windows.sh
|
run: ./.ci/windows.sh
|
||||||
- name: Pack
|
- name: Pack
|
||||||
run: ./.ci/pack.sh
|
run: ./.ci/pack.sh
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
path: artifacts/
|
path: artifacts/
|
||||||
android:
|
android:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
|
||||||
CCACHE_COMPILERCHECK: content
|
|
||||||
CCACHE_SLOPPINESS: time_macros
|
|
||||||
OS: android
|
OS: android
|
||||||
TARGET: universal
|
TARGET: universal
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Set up cache
|
- name: Set up cache
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: |
|
path: |
|
||||||
~/.gradle/caches
|
~/.gradle/caches
|
||||||
~/.gradle/wrapper
|
~/.gradle/wrapper
|
||||||
${{ env.CCACHE_DIR }}
|
~/.ccache
|
||||||
key: ${{ runner.os }}-android-${{ github.sha }}
|
key: ${{ runner.os }}-android-${{ github.sha }}
|
||||||
restore-keys: |
|
restore-keys: |
|
||||||
${{ runner.os }}-android-
|
${{ runner.os }}-android-
|
||||||
|
@ -206,7 +220,7 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
|
sudo add-apt-repository -y ppa:theofficialgman/gpu-tools
|
||||||
sudo apt-get update -y
|
sudo apt-get update -y
|
||||||
sudo apt-get install ccache apksigner -y
|
sudo apt-get install ccache glslang-dev glslang-tools apksigner -y
|
||||||
- name: Build
|
- name: Build
|
||||||
run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh
|
run: JAVA_HOME=$JAVA_HOME_17_X64 ./.ci/android.sh
|
||||||
env:
|
env:
|
||||||
|
@ -217,42 +231,31 @@ jobs:
|
||||||
run: ../../../.ci/pack.sh
|
run: ../../../.ci/pack.sh
|
||||||
working-directory: src/android/app
|
working-directory: src/android/app
|
||||||
env:
|
env:
|
||||||
UNPACKED: 1
|
UPLOAD_RAW: 1
|
||||||
- name: Upload
|
- name: Upload
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: ${{ env.OS }}-${{ env.TARGET }}
|
name: ${{ env.OS }}-${{ env.TARGET }}
|
||||||
path: src/android/app/artifacts/
|
path: src/android/app/artifacts/
|
||||||
ios:
|
transifex:
|
||||||
runs-on: macos-14
|
runs-on: ubuntu-latest
|
||||||
if: ${{ !startsWith(github.ref, 'refs/tags/') }}
|
container: citraemu/build-environments:linux-fresh
|
||||||
env:
|
if: ${{ github.repository == 'citra-emu/citra' && !github.head_ref }}
|
||||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
|
||||||
CCACHE_COMPILERCHECK: content
|
|
||||||
CCACHE_SLOPPINESS: time_macros
|
|
||||||
OS: ios
|
|
||||||
TARGET: arm64
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- name: Set up cache
|
fetch-depth: 0
|
||||||
uses: actions/cache@v4
|
- name: Update Translation
|
||||||
with:
|
run: ./.ci/transifex.sh
|
||||||
path: ${{ env.CCACHE_DIR }}
|
env:
|
||||||
key: ${{ runner.os }}-ios-${{ github.sha }}
|
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-ios-
|
|
||||||
- name: Install tools
|
|
||||||
run: brew install ccache ninja
|
|
||||||
- name: Build
|
|
||||||
run: ./.ci/ios.sh
|
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [windows, linux, macos-universal, android, source]
|
needs: [windows, linux, macos-universal, android, source]
|
||||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v3
|
||||||
- name: Create release
|
- name: Create release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
env:
|
env:
|
22
.github/workflows/format.yml
vendored
22
.github/workflows/format.yml
vendored
|
@ -1,22 +0,0 @@
|
||||||
name: citra-format
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "*" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
clang-format:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container:
|
|
||||||
image: citraemu/build-environments:linux-fresh
|
|
||||||
options: -u 1001
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Build
|
|
||||||
env:
|
|
||||||
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
|
|
||||||
run: ./.ci/clang-format.sh
|
|
16
.github/workflows/publish.yml
vendored
16
.github/workflows/publish.yml
vendored
|
@ -20,11 +20,11 @@ jobs:
|
||||||
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
|
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
|
||||||
steps:
|
steps:
|
||||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Pre-checkout
|
name: Pre-checkout
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@v6
|
||||||
id: check-changes
|
id: check-changes
|
||||||
name: 'Check for new changes'
|
name: 'Check for new changes'
|
||||||
env:
|
env:
|
||||||
|
@ -38,7 +38,7 @@ jobs:
|
||||||
return checkBaseChanges(github, context);
|
return checkBaseChanges(github, context);
|
||||||
- run: npm install execa@5
|
- run: npm install execa@5
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Checkout
|
name: Checkout
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
with:
|
with:
|
||||||
|
@ -46,7 +46,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@v6
|
||||||
name: 'Update and tag new commits'
|
name: 'Update and tag new commits'
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
env:
|
env:
|
||||||
|
@ -62,11 +62,11 @@ jobs:
|
||||||
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
|
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
|
||||||
steps:
|
steps:
|
||||||
# this checkout is required to make sure the GitHub Actions scripts are available
|
# this checkout is required to make sure the GitHub Actions scripts are available
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Pre-checkout
|
name: Pre-checkout
|
||||||
with:
|
with:
|
||||||
submodules: false
|
submodules: false
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@v6
|
||||||
id: check-changes
|
id: check-changes
|
||||||
name: 'Check for new changes'
|
name: 'Check for new changes'
|
||||||
env:
|
env:
|
||||||
|
@ -79,7 +79,7 @@ jobs:
|
||||||
return checkCanaryChanges(github, context);
|
return checkCanaryChanges(github, context);
|
||||||
- run: npm install execa@5
|
- run: npm install execa@5
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v3
|
||||||
name: Checkout
|
name: Checkout
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
with:
|
with:
|
||||||
|
@ -87,7 +87,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
token: ${{ secrets.ALT_GITHUB_TOKEN }}
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@v6
|
||||||
name: 'Check and merge canary changes'
|
name: 'Check and merge canary changes'
|
||||||
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
if: ${{ steps.check-changes.outputs.result == 'true' }}
|
||||||
env:
|
env:
|
||||||
|
|
20
.github/workflows/transifex.yml
vendored
20
.github/workflows/transifex.yml
vendored
|
@ -1,20 +0,0 @@
|
||||||
name: citra-transifex
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ master ]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
transifex:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
container: citraemu/build-environments:linux-fresh
|
|
||||||
if: ${{ github.repository == 'citra-emu/citra' }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
fetch-depth: 0
|
|
||||||
- name: Update Translation
|
|
||||||
run: ./.ci/transifex.sh
|
|
||||||
env:
|
|
||||||
TX_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
|
|
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -9,14 +9,10 @@ src/common/scm_rev.cpp
|
||||||
|
|
||||||
# Project/editor files
|
# Project/editor files
|
||||||
*.swp
|
*.swp
|
||||||
*.kdev4
|
|
||||||
.idea/
|
.idea/
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/
|
.vscode/
|
||||||
.cache/
|
.cache/
|
||||||
.kdev4/
|
|
||||||
cmake-build-debug/
|
|
||||||
cmake-build-release/
|
|
||||||
CMakeLists.txt.user*
|
CMakeLists.txt.user*
|
||||||
|
|
||||||
# *nix related
|
# *nix related
|
||||||
|
@ -45,6 +41,4 @@ Thumbs.db
|
||||||
repo/
|
repo/
|
||||||
|
|
||||||
# GitHub Actions generated files
|
# GitHub Actions generated files
|
||||||
.ccache/
|
|
||||||
node_modules/
|
node_modules/
|
||||||
VULKAN_SDK/
|
|
||||||
|
|
13
.gitmodules
vendored
13
.gitmodules
vendored
|
@ -36,7 +36,7 @@
|
||||||
url = https://github.com/mozilla/cubeb
|
url = https://github.com/mozilla/cubeb
|
||||||
[submodule "discord-rpc"]
|
[submodule "discord-rpc"]
|
||||||
path = externals/discord-rpc
|
path = externals/discord-rpc
|
||||||
url = https://github.com/yuzu-emu/discord-rpc.git
|
url = https://github.com/discord/discord-rpc.git
|
||||||
[submodule "cpp-jwt"]
|
[submodule "cpp-jwt"]
|
||||||
path = externals/cpp-jwt
|
path = externals/cpp-jwt
|
||||||
url = https://github.com/arun11299/cpp-jwt.git
|
url = https://github.com/arun11299/cpp-jwt.git
|
||||||
|
@ -79,15 +79,6 @@
|
||||||
[submodule "sirit"]
|
[submodule "sirit"]
|
||||||
path = externals/sirit
|
path = externals/sirit
|
||||||
url = https://github.com/yuzu-emu/sirit
|
url = https://github.com/yuzu-emu/sirit
|
||||||
[submodule "faad2"]
|
|
||||||
path = externals/faad2/faad2
|
|
||||||
url = https://github.com/knik0/faad2
|
|
||||||
[submodule "library-headers"]
|
[submodule "library-headers"]
|
||||||
path = externals/library-headers
|
path = externals/library-headers/library-headers
|
||||||
url = https://github.com/citra-emu/ext-library-headers.git
|
url = https://github.com/citra-emu/ext-library-headers.git
|
||||||
[submodule "libadrenotools"]
|
|
||||||
path = externals/libadrenotools
|
|
||||||
url = https://github.com/bylaws/libadrenotools
|
|
||||||
[submodule "oaknut"]
|
|
||||||
path = externals/oaknut
|
|
||||||
url = https://github.com/merryhime/oaknut.git
|
|
||||||
|
|
13
.lgtm.yml
Normal file
13
.lgtm.yml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
path_classifiers:
|
||||||
|
library: "externals"
|
||||||
|
extraction:
|
||||||
|
cpp:
|
||||||
|
prepare:
|
||||||
|
packages:
|
||||||
|
- "libsdl2-dev"
|
||||||
|
- "qtmultimedia5-dev"
|
||||||
|
- "clang-format-6.0"
|
||||||
|
- "libtbb-dev"
|
||||||
|
- "libjack-jackd2-dev"
|
||||||
|
- "doxygen"
|
||||||
|
- "graphviz"
|
160
CMakeLists.txt
160
CMakeLists.txt
|
@ -5,10 +5,6 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
cmake_policy(SET CMP0092 NEW)
|
cmake_policy(SET CMP0092 NEW)
|
||||||
# Enforce new LTO setting
|
# Enforce new LTO setting
|
||||||
cmake_policy(SET CMP0069 NEW)
|
cmake_policy(SET CMP0069 NEW)
|
||||||
# Honor visibility properties for all targets
|
|
||||||
# Set the default so subdirectory cmake_minimum_required calls won't unset the policy.
|
|
||||||
cmake_policy(SET CMP0063 NEW)
|
|
||||||
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
|
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||||
|
@ -17,46 +13,17 @@ include(CMakeDependentOption)
|
||||||
|
|
||||||
project(citra LANGUAGES C CXX ASM)
|
project(citra LANGUAGES C CXX ASM)
|
||||||
|
|
||||||
# Some submodules like to pick their own default build type if not specified.
|
if (IOS)
|
||||||
# Make sure we default to Release build type always, unless the generator has custom types.
|
# Enable searching CMAKE_PREFIX_PATH for bundled dependencies.
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
|
||||||
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
|
||||||
endif()
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
|
||||||
|
|
||||||
if (APPLE)
|
|
||||||
# Silence warnings on empty objects, for example when platform-specific code is #ifdef'd out.
|
|
||||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
|
||||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
|
||||||
set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
|
||||||
set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
|
|
||||||
|
|
||||||
if (IOS)
|
|
||||||
# Minimum iOS 14
|
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "14.0")
|
|
||||||
|
|
||||||
# Enable searching CMAKE_PREFIX_PATH for bundled dependencies.
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH)
|
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH)
|
|
||||||
else()
|
|
||||||
# Minimum macOS 11
|
|
||||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
set(IS_DEBUG_BUILD ON)
|
set(IS_DEBUG_BUILD ON)
|
||||||
set(IS_RELEASE_BUILD OFF)
|
|
||||||
else()
|
else()
|
||||||
set(IS_DEBUG_BUILD OFF)
|
set(IS_DEBUG_BUILD OFF)
|
||||||
set(IS_RELEASE_BUILD ON)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# LTO takes too much memory and time using MSVC.
|
|
||||||
if (NOT MSVC AND IS_RELEASE_BUILD)
|
|
||||||
set(DEFAULT_ENABLE_LTO ON)
|
|
||||||
else()
|
|
||||||
set(DEFAULT_ENABLE_LTO OFF)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
option(ENABLE_SDL2 "Enable using SDL2" ON)
|
option(ENABLE_SDL2 "Enable using SDL2" ON)
|
||||||
|
@ -72,35 +39,33 @@ CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_DEDICATED_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_DEDICATED_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||||
|
|
||||||
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||||
option(ENABLE_SCRIPTING "Enable RPC server for scripting" ON)
|
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
|
||||||
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_LIBUSB "Enable libusb for GameCube Adapter support" ON "NOT IOS" OFF)
|
CMAKE_DEPENDENT_OPTION(ENABLE_LIBUSB "Enable libusb for GameCube Adapter support" ON "NOT IOS" OFF)
|
||||||
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_SOFTWARE_RENDERER "Enables the software renderer" ON "NOT ANDROID" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(ENABLE_OPENGL "Enables the OpenGL renderer" ON "NOT APPLE" OFF)
|
|
||||||
option(ENABLE_VULKAN "Enables the Vulkan renderer" ON)
|
|
||||||
|
|
||||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||||
|
|
||||||
|
CMAKE_DEPENDENT_OPTION(ENABLE_MF "Use Media Foundation decoder (preferred over FFmpeg)" ON "WIN32" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(ENABLE_AUDIOTOOLBOX "Use AudioToolbox decoder (preferred over FFmpeg)" ON "APPLE" OFF)
|
||||||
|
|
||||||
# Compile options
|
# Compile options
|
||||||
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ${IS_DEBUG_BUILD} "MINGW" OFF)
|
||||||
option(ENABLE_LTO "Enable link time optimization" ${DEFAULT_ENABLE_LTO})
|
option(ENABLE_LTO "Enable link time optimization" OFF)
|
||||||
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
option(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
|
||||||
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
|
||||||
|
|
||||||
include(CitraHandleSystemLibs)
|
# System library options
|
||||||
|
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_QT "Use the system Qt lib (instead of the bundled one)" OFF "ENABLE_QT;MSVC OR APPLE" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF)
|
||||||
|
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
||||||
|
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
||||||
|
option(USE_SYSTEM_OPENSSL "Use the system OpenSSL libs (instead of the bundled LibreSSL)" OFF)
|
||||||
|
|
||||||
if (CITRA_USE_PRECOMPILED_HEADERS)
|
if (CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
message(STATUS "Using Precompiled Headers.")
|
message(STATUS "Using Precompiled Headers.")
|
||||||
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
set(CMAKE_PCH_INSTANTIATE_TEMPLATES ON)
|
||||||
|
|
||||||
# This ensures that pre-compiled headers won't invalidate build caches for every fresh checkout.
|
|
||||||
if(NOT MSVC AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
||||||
list(APPEND CMAKE_CXX_COMPILE_OPTIONS_CREATE_PCH -Xclang -fno-pch-timestamp)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||||
|
@ -218,10 +183,6 @@ add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE)
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Apply consistent visibility settings.
|
|
||||||
set(CMAKE_CXX_VISIBILITY_PRESET default)
|
|
||||||
set(CMAKE_VISIBILITY_INLINES_HIDDEN NO)
|
|
||||||
|
|
||||||
# set up output paths for executable binaries
|
# set up output paths for executable binaries
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
|
||||||
|
|
||||||
|
@ -235,7 +196,7 @@ find_package(Threads REQUIRED)
|
||||||
|
|
||||||
if (ENABLE_QT)
|
if (ENABLE_QT)
|
||||||
if (NOT USE_SYSTEM_QT)
|
if (NOT USE_SYSTEM_QT)
|
||||||
download_qt(6.6.0)
|
download_qt(6.5.0)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
||||||
|
@ -247,26 +208,19 @@ if (ENABLE_QT)
|
||||||
if (ENABLE_QT_TRANSLATION)
|
if (ENABLE_QT_TRANSLATION)
|
||||||
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if (NOT DEFINED QT_TARGET_PATH)
|
# Ensure libusb is properly configured (based on dolphin libusb include)
|
||||||
# Determine the location of the compile target's Qt.
|
if (ENABLE_LIBUSB)
|
||||||
get_target_property(qtcore_path Qt6::Core LOCATION_Release)
|
if(NOT APPLE)
|
||||||
string(FIND "${qtcore_path}" "/bin/" qtcore_path_bin_pos REVERSE)
|
include(FindPkgConfig)
|
||||||
string(FIND "${qtcore_path}" "/lib/" qtcore_path_lib_pos REVERSE)
|
find_package(LibUSB)
|
||||||
if (qtcore_path_bin_pos GREATER qtcore_path_lib_pos)
|
|
||||||
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_bin_pos} QT_TARGET_PATH)
|
|
||||||
else()
|
|
||||||
string(SUBSTRING "${qtcore_path}" 0 ${qtcore_path_lib_pos} QT_TARGET_PATH)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
if (NOT LIBUSB_FOUND)
|
||||||
if (NOT DEFINED QT_HOST_PATH)
|
add_subdirectory(externals/libusb)
|
||||||
# Use the same for host Qt if none is defined.
|
set(LIBUSB_INCLUDE_DIR "")
|
||||||
set(QT_HOST_PATH "${QT_TARGET_PATH}")
|
set(LIBUSB_LIBRARIES usb)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Using target Qt at ${QT_TARGET_PATH}")
|
|
||||||
message(STATUS "Using host Qt at ${QT_HOST_PATH}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
|
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
|
||||||
|
@ -276,22 +230,20 @@ find_package(tsl-robin-map QUIET)
|
||||||
# ======================================
|
# ======================================
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
if (NOT USE_SYSTEM_MOLTENVK)
|
||||||
|
download_moltenvk()
|
||||||
|
endif()
|
||||||
|
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||||
|
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
||||||
|
|
||||||
if (NOT IOS)
|
if (NOT IOS)
|
||||||
# Umbrella framework for everything GUI-related
|
# Umbrella framework for everything GUI-related
|
||||||
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
find_library(COCOA_LIBRARY Cocoa REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
|
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
|
||||||
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
|
||||||
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOSURFACE_LIBRARY} ${MOLTENVK_LIBRARY})
|
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOSURFACE_LIBRARY} ${MOLTENVK_LIBRARY})
|
||||||
|
|
||||||
if (ENABLE_VULKAN)
|
|
||||||
if (NOT USE_SYSTEM_MOLTENVK)
|
|
||||||
download_moltenvk()
|
|
||||||
endif()
|
|
||||||
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
|
||||||
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
|
||||||
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${MOLTENVK_LIBRARY})
|
|
||||||
endif()
|
|
||||||
elseif (WIN32)
|
elseif (WIN32)
|
||||||
set(PLATFORM_LIBRARIES winmm ws2_32)
|
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
|
@ -306,7 +258,7 @@ endif()
|
||||||
# against all the src files. This should be used before making a pull request.
|
# against all the src files. This should be used before making a pull request.
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
|
|
||||||
set(CLANG_FORMAT_POSTFIX "-15")
|
set(CLANG_FORMAT_POSTFIX "-12")
|
||||||
find_program(CLANG_FORMAT
|
find_program(CLANG_FORMAT
|
||||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||||
clang-format
|
clang-format
|
||||||
|
@ -379,6 +331,13 @@ function(get_timestamp _var)
|
||||||
set(${_var} "${timestamp}" PARENT_SCOPE)
|
set(${_var} "${timestamp}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# Prevent boost from linking against libs when building
|
||||||
|
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
|
||||||
|
-DBOOST_SYSTEM_NO_LIB
|
||||||
|
-DBOOST_DATE_TIME_NO_LIB
|
||||||
|
-DBOOST_REGEX_NO_LIB
|
||||||
|
)
|
||||||
|
|
||||||
# generate git/build information
|
# generate git/build information
|
||||||
include(GetGitRevisionDescription)
|
include(GetGitRevisionDescription)
|
||||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||||
|
@ -386,23 +345,22 @@ git_describe(GIT_DESC --always --long --dirty)
|
||||||
git_branch_name(GIT_BRANCH)
|
git_branch_name(GIT_BRANCH)
|
||||||
get_timestamp(BUILD_DATE)
|
get_timestamp(BUILD_DATE)
|
||||||
|
|
||||||
# Boost
|
if (NOT USE_SYSTEM_BOOST)
|
||||||
# Prevent boost from linking against libs when building
|
add_definitions( -DBOOST_ALL_NO_LIB )
|
||||||
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY
|
|
||||||
-DBOOST_SYSTEM_NO_LIB
|
|
||||||
-DBOOST_DATE_TIME_NO_LIB
|
|
||||||
-DBOOST_REGEX_NO_LIB
|
|
||||||
)
|
|
||||||
if (USE_SYSTEM_BOOST)
|
|
||||||
find_package(Boost 1.70.0 COMPONENTS container locale serialization iostreams REQUIRED)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|
||||||
# Boost (bundled)
|
# See externals/CMakeLists.txt
|
||||||
if (NOT USE_SYSTEM_BOOST)
|
foreach(def ${CRYPTOPP_COMPILE_DEFINITIONS})
|
||||||
add_definitions( -DBOOST_ALL_NO_LIB )
|
add_definitions(-D${def})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Boost
|
||||||
|
if (USE_SYSTEM_BOOST)
|
||||||
|
find_package(Boost 1.70.0 COMPONENTS serialization iostreams REQUIRED)
|
||||||
|
else()
|
||||||
add_library(Boost::boost ALIAS boost)
|
add_library(Boost::boost ALIAS boost)
|
||||||
add_library(Boost::serialization ALIAS boost_serialization)
|
add_library(Boost::serialization ALIAS boost_serialization)
|
||||||
add_library(Boost::iostreams ALIAS boost_iostreams)
|
add_library(Boost::iostreams ALIAS boost_iostreams)
|
||||||
|
@ -417,19 +375,6 @@ if (ENABLE_SDL2 AND USE_SYSTEM_SDL2)
|
||||||
add_library(SDL2::SDL2 ALIAS SDL2)
|
add_library(SDL2::SDL2 ALIAS SDL2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_LIBUSB AND USE_SYSTEM_LIBUSB)
|
|
||||||
include(FindPkgConfig)
|
|
||||||
find_package(LibUSB)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (USE_SYSTEM_SOUNDTOUCH)
|
|
||||||
include(FindPkgConfig)
|
|
||||||
find_package(SoundTouch REQUIRED)
|
|
||||||
add_library(SoundTouch INTERFACE)
|
|
||||||
target_link_libraries(SoundTouch INTERFACE "${SOUNDTOUCH_LIBRARIES}")
|
|
||||||
target_include_directories(SoundTouch INTERFACE "${SOUNDTOUCH_INCLUDE_DIRS}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(dist/installer)
|
add_subdirectory(dist/installer)
|
||||||
|
|
||||||
|
@ -442,7 +387,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Create target for outputting distributable bundles.
|
# Create target for outputting distributable bundles.
|
||||||
# Not supported for mobile platforms as distributables are built differently.
|
|
||||||
if (NOT ANDROID AND NOT IOS)
|
if (NOT ANDROID AND NOT IOS)
|
||||||
include(BundleTarget)
|
include(BundleTarget)
|
||||||
if (ENABLE_SDL2_FRONTEND)
|
if (ENABLE_SDL2_FRONTEND)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# To use this as a script, make sure you pass in the variables BASE_DIR, SRC_DIR, BUILD_DIR, and TARGET_FILE
|
# To use this as a script, make sure you pass in the variables BASE_DIR, SRC_DIR, BUILD_DIR, and TARGET_FILE
|
||||||
cmake_minimum_required(VERSION 3.15)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(PLATFORM "windows")
|
set(PLATFORM "windows")
|
||||||
|
@ -13,8 +12,7 @@ endif()
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
|
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
|
||||||
include(DownloadExternals)
|
include(DownloadExternals)
|
||||||
download_qt(tools_ifw)
|
download_qt(tools_ifw QT_PREFIX)
|
||||||
get_external_prefix(qt QT_PREFIX)
|
|
||||||
|
|
||||||
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
|
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
|
||||||
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
|
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
|
||||||
|
|
|
@ -2,104 +2,37 @@
|
||||||
if (BUNDLE_TARGET_EXECUTE)
|
if (BUNDLE_TARGET_EXECUTE)
|
||||||
# --- Bundling method logic ---
|
# --- Bundling method logic ---
|
||||||
|
|
||||||
function(symlink_safe_copy from to)
|
|
||||||
if (WIN32)
|
|
||||||
# Use cmake copy for maximum compatibility.
|
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${from}" "${to}"
|
|
||||||
RESULT_VARIABLE cp_result)
|
|
||||||
else()
|
|
||||||
# Use native copy to turn symlinks into normal files.
|
|
||||||
execute_process(COMMAND cp -L "${from}" "${to}"
|
|
||||||
RESULT_VARIABLE cp_result)
|
|
||||||
endif()
|
|
||||||
if (NOT cp_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "cp \"${from}\" \"${to}\" failed: ${cp_result}")
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
function(bundle_qt executable_path)
|
function(bundle_qt executable_path)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
# Perform standalone bundling first to copy over all used libraries, as windeployqt does not do this.
|
|
||||||
bundle_standalone("${executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
|
||||||
|
|
||||||
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
|
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
|
||||||
|
find_program(windeployqt_executable windeployqt6)
|
||||||
|
|
||||||
# Create a qt.conf file pointing to the app directory.
|
# Create a qt.conf file pointing to the app directory.
|
||||||
# This ensures Qt can find its plugins.
|
# This ensures Qt can find its plugins.
|
||||||
file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nPrefix = .")
|
file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nprefix = .")
|
||||||
|
|
||||||
find_program(windeployqt_executable windeployqt6 PATHS "${QT_HOST_PATH}/bin")
|
|
||||||
find_program(qtpaths_executable qtpaths6 PATHS "${QT_HOST_PATH}/bin")
|
|
||||||
|
|
||||||
# TODO: Hack around windeployqt's poor cross-compilation support by
|
|
||||||
# TODO: making a local copy with a prefix pointing to the target Qt.
|
|
||||||
if (NOT "${QT_HOST_PATH}" STREQUAL "${QT_TARGET_PATH}")
|
|
||||||
set(windeployqt_dir "${BINARY_PATH}/windeployqt_copy")
|
|
||||||
file(MAKE_DIRECTORY "${windeployqt_dir}")
|
|
||||||
symlink_safe_copy("${windeployqt_executable}" "${windeployqt_dir}/windeployqt.exe")
|
|
||||||
symlink_safe_copy("${qtpaths_executable}" "${windeployqt_dir}/qtpaths.exe")
|
|
||||||
symlink_safe_copy("${QT_HOST_PATH}/bin/Qt6Core.dll" "${windeployqt_dir}")
|
|
||||||
|
|
||||||
if (EXISTS "${QT_TARGET_PATH}/share")
|
|
||||||
# Unix-style Qt; we need to wire up the paths manually.
|
|
||||||
file(WRITE "${windeployqt_dir}/qt.conf" "\
|
|
||||||
[Paths]\n
|
|
||||||
Prefix = ${QT_TARGET_PATH}\n \
|
|
||||||
ArchData = ${QT_TARGET_PATH}/share/qt6\n \
|
|
||||||
Binaries = ${QT_TARGET_PATH}/bin\n \
|
|
||||||
Data = ${QT_TARGET_PATH}/share/qt6\n \
|
|
||||||
Documentation = ${QT_TARGET_PATH}/share/qt6/doc\n \
|
|
||||||
Headers = ${QT_TARGET_PATH}/include/qt6\n \
|
|
||||||
Libraries = ${QT_TARGET_PATH}/lib\n \
|
|
||||||
LibraryExecutables = ${QT_TARGET_PATH}/share/qt6/bin\n \
|
|
||||||
Plugins = ${QT_TARGET_PATH}/share/qt6/plugins\n \
|
|
||||||
QmlImports = ${QT_TARGET_PATH}/share/qt6/qml\n \
|
|
||||||
Translations = ${QT_TARGET_PATH}/share/qt6/translations\n \
|
|
||||||
")
|
|
||||||
else()
|
|
||||||
# Windows-style Qt; the defaults should suffice.
|
|
||||||
file(WRITE "${windeployqt_dir}/qt.conf" "[Paths]\nPrefix = ${QT_TARGET_PATH}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(windeployqt_executable "${windeployqt_dir}/windeployqt.exe")
|
|
||||||
set(qtpaths_executable "${windeployqt_dir}/qtpaths.exe")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Executing windeployqt for executable ${executable_path}")
|
message(STATUS "Executing windeployqt for executable ${executable_path}")
|
||||||
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
|
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
|
||||||
--qtpaths "${qtpaths_executable}"
|
|
||||||
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
|
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
|
||||||
--plugindir "${executable_parent_dir}/plugins"
|
--plugindir "${executable_parent_dir}/plugins")
|
||||||
RESULT_VARIABLE windeployqt_result)
|
|
||||||
if (NOT windeployqt_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "windeployqt failed: ${windeployqt_result}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Remove the FFmpeg multimedia plugin as we don't include FFmpeg.
|
# Remove the FFmpeg multimedia plugin as we don't include FFmpeg.
|
||||||
# We want to use the Windows media plugin instead, which is also included.
|
# We want to use the Windows media plugin instead, which is also included.
|
||||||
file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll")
|
file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll")
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
get_filename_component(executable_name "${executable_path}" NAME_WE)
|
get_filename_component(executable_name "${executable_path}" NAME_WE)
|
||||||
find_program(macdeployqt_executable macdeployqt6 PATHS "${QT_HOST_PATH}/bin")
|
find_program(MACDEPLOYQT_EXECUTABLE macdeployqt6)
|
||||||
|
|
||||||
message(STATUS "Executing macdeployqt at \"${macdeployqt_executable}\" for executable \"${executable_path}\"")
|
message(STATUS "Executing macdeployqt for executable ${executable_path}")
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND "${macdeployqt_executable}"
|
COMMAND "${MACDEPLOYQT_EXECUTABLE}"
|
||||||
"${executable_path}"
|
"${executable_path}"
|
||||||
"-executable=${executable_path}/Contents/MacOS/${executable_name}"
|
"-executable=${executable_path}/Contents/MacOS/${executable_name}"
|
||||||
-always-overwrite
|
-always-overwrite)
|
||||||
RESULT_VARIABLE macdeployqt_result)
|
|
||||||
if (NOT macdeployqt_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "macdeployqt failed: ${macdeployqt_result}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Bundling libraries can rewrite path information and break code signatures of system libraries.
|
# Bundling libraries can rewrite path information and break code signatures of system libraries.
|
||||||
# Perform an ad-hoc re-signing on the whole app bundle to fix this.
|
# Perform an ad-hoc re-signing on the whole app bundle to fix this.
|
||||||
execute_process(COMMAND codesign --deep -fs - "${executable_path}"
|
execute_process(COMMAND codesign --deep -fs - "${executable_path}")
|
||||||
RESULT_VARIABLE codesign_result)
|
|
||||||
if (NOT codesign_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "codesign failed: ${codesign_result}")
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported OS for Qt bundling.")
|
message(FATAL_ERROR "Unsupported OS for Qt bundling.")
|
||||||
endif()
|
endif()
|
||||||
|
@ -111,9 +44,9 @@ if (BUNDLE_TARGET_EXECUTE)
|
||||||
|
|
||||||
if (enable_qt)
|
if (enable_qt)
|
||||||
# Find qmake to make sure the plugin uses the right version of Qt.
|
# Find qmake to make sure the plugin uses the right version of Qt.
|
||||||
find_program(qmake_executable qmake6 PATHS "${QT_HOST_PATH}/bin")
|
find_program(QMAKE_EXECUTABLE qmake6)
|
||||||
|
|
||||||
set(extra_linuxdeploy_env "QMAKE=${qmake_executable}")
|
set(extra_linuxdeploy_env "QMAKE=${QMAKE_EXECUTABLE}")
|
||||||
set(extra_linuxdeploy_args --plugin qt)
|
set(extra_linuxdeploy_args --plugin qt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -126,11 +59,7 @@ if (BUNDLE_TARGET_EXECUTE)
|
||||||
--executable "${executable_path}"
|
--executable "${executable_path}"
|
||||||
--icon-file "${source_path}/dist/citra.svg"
|
--icon-file "${source_path}/dist/citra.svg"
|
||||||
--desktop-file "${source_path}/dist/${executable_name}.desktop"
|
--desktop-file "${source_path}/dist/${executable_name}.desktop"
|
||||||
--appdir "${appdir_path}"
|
--appdir "${appdir_path}")
|
||||||
RESULT_VARIABLE linuxdeploy_appdir_result)
|
|
||||||
if (NOT linuxdeploy_appdir_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "linuxdeploy failed to create AppDir: ${linuxdeploy_appdir_result}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (enable_qt)
|
if (enable_qt)
|
||||||
set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh")
|
set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh")
|
||||||
|
@ -153,11 +82,7 @@ if (BUNDLE_TARGET_EXECUTE)
|
||||||
"OUTPUT=${bundle_dir}/${executable_name}.AppImage"
|
"OUTPUT=${bundle_dir}/${executable_name}.AppImage"
|
||||||
"${linuxdeploy_executable}"
|
"${linuxdeploy_executable}"
|
||||||
--output appimage
|
--output appimage
|
||||||
--appdir "${appdir_path}"
|
--appdir "${appdir_path}")
|
||||||
RESULT_VARIABLE linuxdeploy_appimage_result)
|
|
||||||
if (NOT linuxdeploy_appimage_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "linuxdeploy failed to create AppImage: ${linuxdeploy_appimage_result}")
|
|
||||||
endif()
|
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(bundle_standalone executable_path original_executable_path bundle_library_paths)
|
function(bundle_standalone executable_path original_executable_path bundle_library_paths)
|
||||||
|
@ -184,56 +109,43 @@ if (BUNDLE_TARGET_EXECUTE)
|
||||||
file(MAKE_DIRECTORY ${lib_dir})
|
file(MAKE_DIRECTORY ${lib_dir})
|
||||||
foreach (lib_file IN LISTS resolved_deps)
|
foreach (lib_file IN LISTS resolved_deps)
|
||||||
message(STATUS "Bundling library ${lib_file}")
|
message(STATUS "Bundling library ${lib_file}")
|
||||||
symlink_safe_copy("${lib_file}" "${lib_dir}")
|
# Use native copy to turn symlinks into normal files.
|
||||||
|
execute_process(COMMAND cp -L "${lib_file}" "${lib_dir}")
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Add libs directory to executable rpath where applicable.
|
# Add libs directory to executable rpath where applicable.
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}"
|
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}")
|
||||||
RESULT_VARIABLE install_name_tool_result)
|
|
||||||
if (NOT install_name_tool_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "install_name_tool failed: ${install_name_tool_result}")
|
|
||||||
endif()
|
|
||||||
elseif (UNIX)
|
elseif (UNIX)
|
||||||
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}"
|
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}")
|
||||||
RESULT_VARIABLE patchelf_result)
|
|
||||||
if (NOT patchelf_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "patchelf failed: ${patchelf_result}")
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# --- Root bundling logic ---
|
# --- Root bundling logic ---
|
||||||
|
|
||||||
set(bundle_dir ${BINARY_PATH}/bundle)
|
set(bundle_dir ${BINARY_PATH}/bundle)
|
||||||
|
file(MAKE_DIRECTORY ${bundle_dir})
|
||||||
|
|
||||||
# On Linux, always bundle an AppImage.
|
# On Linux, always bundle an AppImage.
|
||||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
if (DEFINED LINUXDEPLOY)
|
||||||
if (IN_PLACE)
|
|
||||||
message(FATAL_ERROR "Cannot bundle for Linux in-place.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
bundle_appimage("${bundle_dir}" "${EXECUTABLE_PATH}" "${SOURCE_PATH}" "${BINARY_PATH}" "${LINUXDEPLOY}" ${BUNDLE_QT})
|
bundle_appimage("${bundle_dir}" "${EXECUTABLE_PATH}" "${SOURCE_PATH}" "${BINARY_PATH}" "${LINUXDEPLOY}" ${BUNDLE_QT})
|
||||||
else()
|
else()
|
||||||
if (IN_PLACE)
|
message(STATUS "Copying base executable ${EXECUTABLE_PATH} to output directory ${bundle_dir}")
|
||||||
message(STATUS "Bundling dependencies in-place")
|
file(COPY ${EXECUTABLE_PATH} DESTINATION ${bundle_dir})
|
||||||
set(bundled_executable_path "${EXECUTABLE_PATH}")
|
get_filename_component(bundled_executable_name "${EXECUTABLE_PATH}" NAME)
|
||||||
else()
|
set(bundled_executable_path "${bundle_dir}/${bundled_executable_name}")
|
||||||
message(STATUS "Copying base executable ${EXECUTABLE_PATH} to output directory ${bundle_dir}")
|
|
||||||
file(COPY ${EXECUTABLE_PATH} DESTINATION ${bundle_dir})
|
|
||||||
get_filename_component(bundled_executable_name "${EXECUTABLE_PATH}" NAME)
|
|
||||||
set(bundled_executable_path "${bundle_dir}/${bundled_executable_name}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUNDLE_QT)
|
if (BUNDLE_QT)
|
||||||
bundle_qt("${bundled_executable_path}")
|
bundle_qt("${bundled_executable_path}")
|
||||||
else()
|
endif()
|
||||||
|
|
||||||
|
if (WIN32 OR NOT BUNDLE_QT)
|
||||||
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
|
else()
|
||||||
# --- linuxdeploy download logic ---
|
# --- Bundling target creation logic ---
|
||||||
|
|
||||||
# Downloads and extracts a linuxdeploy component.
|
# Downloads and extracts a linuxdeploy component.
|
||||||
function(download_linuxdeploy_component base_dir name executable_name)
|
function(download_linuxdeploy_component base_dir name executable_name)
|
||||||
|
@ -241,7 +153,7 @@ elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
|
||||||
if (NOT EXISTS "${executable_file}")
|
if (NOT EXISTS "${executable_file}")
|
||||||
message(STATUS "Downloading ${executable_name}")
|
message(STATUS "Downloading ${executable_name}")
|
||||||
file(DOWNLOAD
|
file(DOWNLOAD
|
||||||
"https://github.com/${name}/releases/download/continuous/${executable_name}"
|
"https://github.com/linuxdeploy/${name}/releases/download/continuous/${executable_name}"
|
||||||
"${executable_file}" SHOW_PROGRESS)
|
"${executable_file}" SHOW_PROGRESS)
|
||||||
file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
|
||||||
|
|
||||||
|
@ -250,11 +162,7 @@ elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
|
||||||
message(STATUS "Extracting ${executable_name}")
|
message(STATUS "Extracting ${executable_name}")
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND "${executable_file}" --appimage-extract
|
COMMAND "${executable_file}" --appimage-extract
|
||||||
WORKING_DIRECTORY "${base_dir}"
|
WORKING_DIRECTORY "${base_dir}")
|
||||||
RESULT_VARIABLE extract_result)
|
|
||||||
if (NOT extract_result EQUAL "0")
|
|
||||||
message(FATAL_ERROR "AppImage extract failed: ${extract_result}")
|
|
||||||
endif()
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Copying ${executable_name}")
|
message(STATUS "Copying ${executable_name}")
|
||||||
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
|
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
|
||||||
|
@ -262,113 +170,74 @@ elseif (BUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
|
# Adds a target to the bundle target, packing in required libraries.
|
||||||
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-${LINUXDEPLOY_ARCH}.AppImage")
|
function(bundle_target target_name)
|
||||||
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "darealshinji/linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt.sh")
|
# Create base bundle target if it does not exist.
|
||||||
download_linuxdeploy_component("${LINUXDEPLOY_PATH}" "linuxdeploy/linuxdeploy" "linuxdeploy-${LINUXDEPLOY_ARCH}.AppImage")
|
if (NOT TARGET bundle)
|
||||||
else()
|
message(STATUS "Creating base bundle target")
|
||||||
# --- Bundling target creation logic ---
|
|
||||||
|
|
||||||
# Creates the base bundle target with common files and pre-bundle steps.
|
add_custom_target(bundle)
|
||||||
function(create_base_bundle_target)
|
|
||||||
message(STATUS "Creating base bundle target")
|
|
||||||
|
|
||||||
add_custom_target(bundle)
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/")
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/bundle/dist/")
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/dist/icon.png" "${CMAKE_BINARY_DIR}/bundle/dist/citra.png")
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_BINARY_DIR}/bundle/")
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/README.md" "${CMAKE_BINARY_DIR}/bundle/")
|
|
||||||
add_custom_command(
|
|
||||||
TARGET bundle
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/dist/scripting" "${CMAKE_BINARY_DIR}/bundle/scripting")
|
|
||||||
|
|
||||||
# On Linux, add a command to prepare linuxdeploy and any required plugins before any bundling occurs.
|
|
||||||
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
TARGET bundle
|
TARGET bundle
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/license.txt" "${CMAKE_BINARY_DIR}/bundle/")
|
||||||
"-DBUNDLE_TARGET_DOWNLOAD_LINUXDEPLOY=1"
|
add_custom_command(
|
||||||
"-DLINUXDEPLOY_PATH=${CMAKE_BINARY_DIR}/externals/linuxdeploy"
|
TARGET bundle
|
||||||
"-DLINUXDEPLOY_ARCH=${CMAKE_HOST_SYSTEM_PROCESSOR}"
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/README.md" "${CMAKE_BINARY_DIR}/bundle/")
|
||||||
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
add_custom_command(
|
||||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
TARGET bundle
|
||||||
endif()
|
COMMAND ${CMAKE_COMMAND} -E copy_directory "${CMAKE_SOURCE_DIR}/dist/scripting" "${CMAKE_BINARY_DIR}/bundle/scripting")
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Adds a target to the bundle target, packing in required libraries.
|
|
||||||
# If in_place is true, the bundling will be done in-place as part of the specified target.
|
|
||||||
function(bundle_target_internal target_name in_place)
|
|
||||||
# Create base bundle target if it does not exist.
|
|
||||||
if (NOT in_place AND NOT TARGET bundle)
|
|
||||||
create_base_bundle_target()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(bundle_executable_path "$<TARGET_FILE:${target_name}>")
|
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_FILE:${target_name}>")
|
||||||
if (target_name MATCHES ".*qt")
|
if (target_name MATCHES ".*qt")
|
||||||
set(bundle_qt ON)
|
set(BUNDLE_QT ON)
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
# For Qt targets on Apple, expect an app bundle.
|
# For Qt targets on Apple, expect an app bundle.
|
||||||
set(bundle_executable_path "$<TARGET_BUNDLE_DIR:${target_name}>")
|
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_BUNDLE_DIR:${target_name}>")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(bundle_qt OFF)
|
set(BUNDLE_QT OFF)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Build a list of library search paths from prefix paths.
|
# Build a list of library search paths from prefix paths.
|
||||||
foreach(prefix_path IN LISTS CMAKE_FIND_ROOT_PATH CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH)
|
foreach(prefix_path IN LISTS CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH)
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
list(APPEND bundle_library_paths "${prefix_path}/bin")
|
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/bin")
|
||||||
endif()
|
endif()
|
||||||
list(APPEND bundle_library_paths "${prefix_path}/lib")
|
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/lib")
|
||||||
endforeach()
|
endforeach()
|
||||||
foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH)
|
foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH)
|
||||||
list(APPEND bundle_library_paths "${library_path}")
|
list(APPEND BUNDLE_LIBRARY_PATHS "${library_path}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
if (in_place)
|
# On Linux, prepare linuxdeploy and any required plugins.
|
||||||
message(STATUS "Adding in-place bundling to ${target_name}")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||||
set(dest_target ${target_name})
|
set(LINUXDEPLOY_BASE "${CMAKE_BINARY_DIR}/externals/linuxdeploy")
|
||||||
else()
|
|
||||||
message(STATUS "Adding ${target_name} to bundle target")
|
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
|
||||||
set(dest_target bundle)
|
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-x86_64.AppImage")
|
||||||
add_dependencies(bundle ${target_name})
|
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-checkrt" "linuxdeploy-plugin-checkrt-x86_64.sh")
|
||||||
|
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy" "linuxdeploy-x86_64.AppImage")
|
||||||
|
|
||||||
|
set(EXTRA_BUNDLE_ARGS "-DLINUXDEPLOY=${LINUXDEPLOY_BASE}/squashfs-root/AppRun")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_custom_command(TARGET ${dest_target} POST_BUILD
|
message(STATUS "Adding ${target_name} to bundle target")
|
||||||
|
|
||||||
|
add_custom_target(bundle-${target_name}
|
||||||
COMMAND ${CMAKE_COMMAND}
|
COMMAND ${CMAKE_COMMAND}
|
||||||
"-DQT_HOST_PATH=\"${QT_HOST_PATH}\""
|
"-DCMAKE_PREFIX_PATH=\"${CMAKE_PREFIX_PATH}\""
|
||||||
"-DQT_TARGET_PATH=\"${QT_TARGET_PATH}\""
|
|
||||||
"-DBUNDLE_TARGET_EXECUTE=1"
|
"-DBUNDLE_TARGET_EXECUTE=1"
|
||||||
"-DTARGET=${target_name}"
|
"-DTARGET=${target_name}"
|
||||||
"-DSOURCE_PATH=${CMAKE_SOURCE_DIR}"
|
"-DSOURCE_PATH=${CMAKE_SOURCE_DIR}"
|
||||||
"-DBINARY_PATH=${CMAKE_BINARY_DIR}"
|
"-DBINARY_PATH=${CMAKE_BINARY_DIR}"
|
||||||
"-DEXECUTABLE_PATH=${bundle_executable_path}"
|
"-DEXECUTABLE_PATH=${BUNDLE_EXECUTABLE_PATH}"
|
||||||
"-DBUNDLE_LIBRARY_PATHS=\"${bundle_library_paths}\""
|
"-DBUNDLE_LIBRARY_PATHS=\"${BUNDLE_LIBRARY_PATHS}\""
|
||||||
"-DBUNDLE_QT=${bundle_qt}"
|
"-DBUNDLE_QT=${BUNDLE_QT}"
|
||||||
"-DIN_PLACE=${in_place}"
|
${EXTRA_BUNDLE_ARGS}
|
||||||
"-DLINUXDEPLOY=${CMAKE_BINARY_DIR}/externals/linuxdeploy/squashfs-root/AppRun"
|
|
||||||
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
|
||||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
endfunction()
|
DEPENDS ${target_name})
|
||||||
|
add_dependencies(bundle bundle-${target_name})
|
||||||
# Adds a target to the bundle target, packing in required libraries.
|
|
||||||
function(bundle_target target_name)
|
|
||||||
bundle_target_internal("${target_name}" OFF)
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Bundles the target in-place, packing in required libraries.
|
|
||||||
function(bundle_target_in_place target_name)
|
|
||||||
bundle_target_internal("${target_name}" ON)
|
|
||||||
endfunction()
|
endfunction()
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -1,61 +1,39 @@
|
||||||
|
|
||||||
set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
# This function downloads Qt using aqt.
|
||||||
|
# Params:
|
||||||
# Determines parameters based on the host and target for downloading the right Qt binaries.
|
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
|
||||||
function(determine_qt_parameters target host_out type_out arch_out arch_path_out host_type_out host_arch_out host_arch_path_out)
|
# prefix_var: Name of a variable which will be set with the path to the extracted contents.
|
||||||
if (target MATCHES "tools_.*")
|
function(download_qt target)
|
||||||
set(tool ON)
|
|
||||||
else()
|
|
||||||
set(tool OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Determine installation parameters for OS, architecture, and compiler
|
# Determine installation parameters for OS, architecture, and compiler
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(host "windows")
|
set(host "windows")
|
||||||
set(type "desktop")
|
set(type "desktop")
|
||||||
|
if (MINGW)
|
||||||
if (NOT tool)
|
set(arch "win64_mingw")
|
||||||
if (MINGW)
|
set(arch_path "mingw_64")
|
||||||
set(arch "win64_mingw")
|
elseif (MSVC)
|
||||||
set(arch_path "mingw_64")
|
if ("arm64" IN_LIST ARCHITECTURE)
|
||||||
elseif (MSVC)
|
set(arch_path "msvc2019_arm64")
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
elseif ("x86_64" IN_LIST ARCHITECTURE)
|
||||||
set(arch_path "msvc2019_arm64")
|
set(arch_path "msvc2019_64")
|
||||||
elseif ("x86_64" IN_LIST ARCHITECTURE)
|
|
||||||
set(arch_path "msvc2019_64")
|
|
||||||
else()
|
|
||||||
message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.")
|
|
||||||
endif()
|
|
||||||
set(arch "win64_${arch_path}")
|
|
||||||
|
|
||||||
# In case we're cross-compiling, prepare to also fetch the correct host Qt tools.
|
|
||||||
if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
|
||||||
set(host_arch_path "msvc2019_64")
|
|
||||||
elseif (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "ARM64")
|
|
||||||
# TODO: msvc2019_arm64 doesn't include some of the required tools for some reason,
|
|
||||||
# TODO: so until it does, just use msvc2019_64 under x86_64 emulation.
|
|
||||||
# set(host_arch_path "msvc2019_arm64")
|
|
||||||
set(host_arch_path "msvc2019_64")
|
|
||||||
endif()
|
|
||||||
set(host_arch "win64_${host_arch_path}")
|
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.")
|
message(FATAL_ERROR "Unsupported bundled Qt architecture. Enable USE_SYSTEM_QT and provide your own.")
|
||||||
endif()
|
endif()
|
||||||
|
set(arch "win64_${arch_path}")
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.")
|
||||||
endif()
|
endif()
|
||||||
elseif (APPLE)
|
elseif (APPLE)
|
||||||
set(host "mac")
|
set(host "mac")
|
||||||
set(type "desktop")
|
if (IOS)
|
||||||
set(arch "clang_64")
|
|
||||||
set(arch_path "macos")
|
|
||||||
|
|
||||||
if (IOS AND NOT tool)
|
|
||||||
set(host_type "${type}")
|
|
||||||
set(host_arch "${arch}")
|
|
||||||
set(host_arch_path "${arch_path}")
|
|
||||||
|
|
||||||
set(type "ios")
|
set(type "ios")
|
||||||
set(arch "ios")
|
set(arch "ios")
|
||||||
set(arch_path "ios")
|
set(arch_path "ios")
|
||||||
|
set(host_arch_path "macos")
|
||||||
|
else()
|
||||||
|
set(type "desktop")
|
||||||
|
set(arch "clang_64")
|
||||||
|
set(arch_path "macos")
|
||||||
endif()
|
endif()
|
||||||
else()
|
else()
|
||||||
set(host "linux")
|
set(host "linux")
|
||||||
|
@ -64,65 +42,28 @@ function(determine_qt_parameters target host_out type_out arch_out arch_path_out
|
||||||
set(arch_path "linux")
|
set(arch_path "linux")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(${host_out} "${host}" PARENT_SCOPE)
|
get_external_prefix(qt base_path)
|
||||||
set(${type_out} "${type}" PARENT_SCOPE)
|
file(MAKE_DIRECTORY "${base_path}")
|
||||||
set(${arch_out} "${arch}" PARENT_SCOPE)
|
|
||||||
set(${arch_path_out} "${arch_path}" PARENT_SCOPE)
|
|
||||||
if (DEFINED host_type)
|
|
||||||
set(${host_type_out} "${host_type}" PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${host_type_out} "${type}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
if (DEFINED host_arch)
|
|
||||||
set(${host_arch_out} "${host_arch}" PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${host_arch_out} "${arch}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
if (DEFINED host_arch_path)
|
|
||||||
set(${host_arch_path_out} "${host_arch_path}" PARENT_SCOPE)
|
|
||||||
else()
|
|
||||||
set(${host_arch_path_out} "${arch_path}" PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Download Qt binaries for a specifc configuration.
|
|
||||||
function(download_qt_configuration prefix_out target host type arch arch_path base_path)
|
|
||||||
if (target MATCHES "tools_.*")
|
if (target MATCHES "tools_.*")
|
||||||
set(tool ON)
|
set(prefix "${base_path}")
|
||||||
else()
|
set(install_args install-tool --outputdir ${base_path} ${host} desktop ${target})
|
||||||
set(tool OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini")
|
|
||||||
if (tool)
|
|
||||||
set(prefix "${base_path}/Tools")
|
|
||||||
set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target})
|
|
||||||
else()
|
else()
|
||||||
set(prefix "${base_path}/${target}/${arch_path}")
|
set(prefix "${base_path}/${target}/${arch_path}")
|
||||||
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch}
|
if (host_arch_path)
|
||||||
-m qtmultimedia --archives qttranslations qttools qtsvg qtbase)
|
set(host_flag "--autodesktop")
|
||||||
|
set(host_prefix "${base_path}/${target}/${host_arch_path}")
|
||||||
|
endif()
|
||||||
|
set(install_args install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} ${host_flag} -m qtmultimedia)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT EXISTS "${prefix}")
|
if (NOT EXISTS "${prefix}")
|
||||||
message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}")
|
message(STATUS "Downloading binaries for Qt...")
|
||||||
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.9")
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(aqt_path "${base_path}/aqt.exe")
|
set(aqt_path "${base_path}/aqt.exe")
|
||||||
if (NOT EXISTS "${aqt_path}")
|
file(DOWNLOAD
|
||||||
file(DOWNLOAD
|
https://github.com/miurahr/aqtinstall/releases/download/v3.1.4/aqt.exe
|
||||||
${AQT_PREBUILD_BASE_URL}/aqt.exe
|
${aqt_path} SHOW_PROGRESS)
|
||||||
${aqt_path} SHOW_PROGRESS)
|
|
||||||
endif()
|
|
||||||
execute_process(COMMAND ${aqt_path} ${install_args}
|
|
||||||
WORKING_DIRECTORY ${base_path})
|
|
||||||
elseif (APPLE)
|
|
||||||
set(aqt_path "${base_path}/aqt-macos")
|
|
||||||
if (NOT EXISTS "${aqt_path}")
|
|
||||||
file(DOWNLOAD
|
|
||||||
${AQT_PREBUILD_BASE_URL}/aqt-macos
|
|
||||||
${aqt_path} SHOW_PROGRESS)
|
|
||||||
endif()
|
|
||||||
execute_process(COMMAND chmod +x ${aqt_path})
|
|
||||||
execute_process(COMMAND ${aqt_path} ${install_args}
|
execute_process(COMMAND ${aqt_path} ${install_args}
|
||||||
WORKING_DIRECTORY ${base_path})
|
WORKING_DIRECTORY ${base_path})
|
||||||
else()
|
else()
|
||||||
|
@ -135,38 +76,18 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args}
|
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args}
|
||||||
WORKING_DIRECTORY ${base_path})
|
WORKING_DIRECTORY ${base_path})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Downloaded Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path} to ${prefix}")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(${prefix_out} "${prefix}" PARENT_SCOPE)
|
message(STATUS "Using downloaded Qt binaries at ${prefix}")
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# This function downloads Qt using aqt.
|
# Add the Qt prefix path so CMake can locate it.
|
||||||
# The path of the downloaded content will be added to the CMAKE_PREFIX_PATH.
|
|
||||||
# QT_TARGET_PATH is set to the Qt for the compile target platform.
|
|
||||||
# QT_HOST_PATH is set to a host-compatible Qt, for running tools.
|
|
||||||
# Params:
|
|
||||||
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
|
|
||||||
function(download_qt target)
|
|
||||||
determine_qt_parameters("${target}" host type arch arch_path host_type host_arch host_arch_path)
|
|
||||||
|
|
||||||
get_external_prefix(qt base_path)
|
|
||||||
file(MAKE_DIRECTORY "${base_path}")
|
|
||||||
|
|
||||||
download_qt_configuration(prefix "${target}" "${host}" "${type}" "${arch}" "${arch_path}" "${base_path}")
|
|
||||||
if (DEFINED host_arch_path AND NOT "${host_arch_path}" STREQUAL "${arch_path}")
|
|
||||||
download_qt_configuration(host_prefix "${target}" "${host}" "${host_type}" "${host_arch}" "${host_arch_path}" "${base_path}")
|
|
||||||
else()
|
|
||||||
set(host_prefix "${prefix}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(QT_TARGET_PATH "${prefix}" CACHE STRING "")
|
|
||||||
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
|
|
||||||
|
|
||||||
# Add the target Qt prefix path so CMake can locate it.
|
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${prefix}")
|
list(APPEND CMAKE_PREFIX_PATH "${prefix}")
|
||||||
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
|
||||||
|
|
||||||
|
if (DEFINED host_prefix)
|
||||||
|
message(STATUS "Using downloaded host Qt binaries at ${host_prefix}")
|
||||||
|
set(QT_HOST_PATH "${host_prefix}" CACHE STRING "")
|
||||||
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(download_moltenvk)
|
function(download_moltenvk)
|
||||||
|
@ -180,7 +101,7 @@ function(download_moltenvk)
|
||||||
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
|
||||||
if (NOT EXISTS ${MOLTENVK_DIR})
|
if (NOT EXISTS ${MOLTENVK_DIR})
|
||||||
if (NOT EXISTS ${MOLTENVK_TAR})
|
if (NOT EXISTS ${MOLTENVK_TAR})
|
||||||
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/download/v1.2.7-rc2/MoltenVK-all.tar
|
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/latest/download/MoltenVK-all.tar
|
||||||
${MOLTENVK_TAR} SHOW_PROGRESS)
|
${MOLTENVK_TAR} SHOW_PROGRESS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,9 @@ if (DEFINED ENV{CI})
|
||||||
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
set(BUILD_VERSION ${CMAKE_MATCH_1})
|
||||||
endif()
|
endif()
|
||||||
if (BUILD_VERSION)
|
if (BUILD_VERSION)
|
||||||
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION}")
|
# This leaves a trailing space on the last word, but we actually want that
|
||||||
|
# because of how it's styled in the title bar.
|
||||||
|
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION} ")
|
||||||
else()
|
else()
|
||||||
set(BUILD_FULLNAME "")
|
set(BUILD_FULLNAME "")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -4,36 +4,26 @@ include(GenerateBuildInfo)
|
||||||
# The variable SRC_DIR must be passed into the script (since it uses the current build directory for all values of CMAKE_*_DIR)
|
# The variable SRC_DIR must be passed into the script (since it uses the current build directory for all values of CMAKE_*_DIR)
|
||||||
set(VIDEO_CORE "${SRC_DIR}/src/video_core")
|
set(VIDEO_CORE "${SRC_DIR}/src/video_core")
|
||||||
set(HASH_FILES
|
set(HASH_FILES
|
||||||
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_decompiler.cpp"
|
||||||
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_decompiler.h"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.cpp"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.cpp"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.h"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_disk_cache.h"
|
||||||
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_gen.cpp"
|
||||||
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_gen.h"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.cpp"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.cpp"
|
||||||
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.h"
|
"${VIDEO_CORE}/renderer_opengl/gl_shader_util.h"
|
||||||
"${VIDEO_CORE}/renderer_vulkan/vk_shader_util.cpp"
|
|
||||||
"${VIDEO_CORE}/renderer_vulkan/vk_shader_util.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_fs_shader_gen.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_fs_shader_gen.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_shader_decompiler.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_shader_decompiler.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_shader_gen.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/glsl_shader_gen.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/pica_fs_config.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/pica_fs_config.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/shader_gen.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/shader_gen.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/shader_uniforms.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/shader_uniforms.h"
|
|
||||||
"${VIDEO_CORE}/shader/generator/spv_fs_shader_gen.cpp"
|
|
||||||
"${VIDEO_CORE}/shader/generator/spv_fs_shader_gen.h"
|
|
||||||
"${VIDEO_CORE}/shader/shader.cpp"
|
"${VIDEO_CORE}/shader/shader.cpp"
|
||||||
"${VIDEO_CORE}/shader/shader.h"
|
"${VIDEO_CORE}/shader/shader.h"
|
||||||
"${VIDEO_CORE}/pica/regs_framebuffer.h"
|
"${VIDEO_CORE}/pica.cpp"
|
||||||
"${VIDEO_CORE}/pica/regs_lighting.h"
|
"${VIDEO_CORE}/pica.h"
|
||||||
"${VIDEO_CORE}/pica/regs_pipeline.h"
|
"${VIDEO_CORE}/regs_framebuffer.h"
|
||||||
"${VIDEO_CORE}/pica/regs_rasterizer.h"
|
"${VIDEO_CORE}/regs_lighting.h"
|
||||||
"${VIDEO_CORE}/pica/regs_shader.h"
|
"${VIDEO_CORE}/regs_pipeline.h"
|
||||||
"${VIDEO_CORE}/pica/regs_texturing.h"
|
"${VIDEO_CORE}/regs_rasterizer.h"
|
||||||
"${VIDEO_CORE}/pica/regs_internal.cpp"
|
"${VIDEO_CORE}/regs_shader.h"
|
||||||
"${VIDEO_CORE}/pica/regs_internal.h"
|
"${VIDEO_CORE}/regs_texturing.h"
|
||||||
|
"${VIDEO_CORE}/regs.cpp"
|
||||||
|
"${VIDEO_CORE}/regs.h"
|
||||||
)
|
)
|
||||||
set(COMBINED "")
|
set(COMBINED "")
|
||||||
foreach (F IN LISTS HASH_FILES)
|
foreach (F IN LISTS HASH_FILES)
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
[aqt]
|
|
||||||
concurrency: 2
|
|
||||||
|
|
||||||
[mirrors]
|
|
||||||
trusted_mirrors:
|
|
||||||
https://download.qt.io
|
|
||||||
blacklist:
|
|
||||||
https://qt.mirror.constant.com
|
|
||||||
https://mirrors.ocf.berkeley.edu
|
|
||||||
https://mirrors.ustc.edu.cn
|
|
||||||
https://mirrors.tuna.tsinghua.edu.cn
|
|
||||||
https://mirrors.geekpie.club
|
|
||||||
https://mirrors-wan.geekpie.club
|
|
||||||
https://mirrors.sjtug.sjtu.edu.cn
|
|
||||||
fallbacks:
|
|
||||||
https://qtproject.mirror.liquidtelecom.com/
|
|
||||||
https://mirrors.aliyun.com/qt/
|
|
||||||
https://ftp.jaist.ac.jp/pub/qtproject/
|
|
||||||
https://ftp.yz.yamagata-u.ac.jp/pub/qtproject/
|
|
||||||
https://qt-mirror.dannhauer.de/
|
|
||||||
https://ftp.fau.de/qtproject/
|
|
||||||
https://mirror.netcologne.de/qtproject/
|
|
||||||
https://mirrors.dotsrc.org/qtproject/
|
|
||||||
https://www.nic.funet.fi/pub/mirrors/download.qt-project.org/
|
|
||||||
https://master.qt.io/
|
|
||||||
https://mirrors.ukfast.co.uk/sites/qt.io/
|
|
||||||
https://ftp2.nluug.nl/languages/qt/
|
|
||||||
https://ftp1.nluug.nl/languages/qt/
|
|
||||||
|
|
34
dist/apple/Info.plist.in
vendored
34
dist/apple/Info.plist.in
vendored
|
@ -21,43 +21,9 @@
|
||||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||||
<key>LSMinimumSystemVersion</key>
|
|
||||||
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
|
|
||||||
<!-- Fixed -->
|
<!-- Fixed -->
|
||||||
<key>LSApplicationCategoryType</key>
|
<key>LSApplicationCategoryType</key>
|
||||||
<string>public.app-category.games</string>
|
<string>public.app-category.games</string>
|
||||||
<key>CFBundleDocumentTypes</key>
|
|
||||||
<array>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleTypeExtensions</key>
|
|
||||||
<array>
|
|
||||||
<string>3ds</string>
|
|
||||||
<string>3dsx</string>
|
|
||||||
<string>cci</string>
|
|
||||||
<string>cxi</string>
|
|
||||||
<string>cia</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleTypeName</key>
|
|
||||||
<string>Nintendo 3DS File</string>
|
|
||||||
<key>CFBundleTypeRole</key>
|
|
||||||
<string>Viewer</string>
|
|
||||||
<key>LSHandlerRank</key>
|
|
||||||
<string>Default</string>
|
|
||||||
</dict>
|
|
||||||
<dict>
|
|
||||||
<key>CFBundleTypeExtensions</key>
|
|
||||||
<array>
|
|
||||||
<string>elf</string>
|
|
||||||
<string>axf</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleTypeName</key>
|
|
||||||
<string>Unix Executable and Linkable Format</string>
|
|
||||||
<key>CFBundleTypeRole</key>
|
|
||||||
<string>Viewer</string>
|
|
||||||
<key>LSHandlerRank</key>
|
|
||||||
<string>Alternate</string>
|
|
||||||
</dict>
|
|
||||||
</array>
|
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>This app requires camera access to emulate the 3DS's cameras.</string>
|
<string>This app requires camera access to emulate the 3DS's cameras.</string>
|
||||||
<key>NSMicrophoneUsageDescription</key>
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
|
8
dist/dumpkeys/DumpKeys.gm9
vendored
8
dist/dumpkeys/DumpKeys.gm9
vendored
|
@ -287,13 +287,5 @@ dumptxt -p $[OUT] "nfcSecret1Seed=$[NFC_SEED_1]"
|
||||||
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
|
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
|
||||||
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
|
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
|
||||||
|
|
||||||
# Dump seeddb.bin as well
|
|
||||||
|
|
||||||
set SEEDDB_IN "0:/gm9/out/seeddb.bin"
|
|
||||||
set SEEDDB_OUT "0:/gm9/seeddb.bin"
|
|
||||||
|
|
||||||
sdump -w seeddb.bin
|
|
||||||
cp -w $[SEEDDB_IN] $[SEEDDB_OUT]
|
|
||||||
|
|
||||||
@Exit
|
@Exit
|
||||||
|
|
||||||
|
|
2
dist/dumpkeys/README.md
vendored
2
dist/dumpkeys/README.md
vendored
|
@ -6,5 +6,5 @@ Usage:
|
||||||
1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card.
|
1. Copy "DumpKeys.gm9" into the "gm9/scripts/" directory on your SD card.
|
||||||
2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears.
|
2. Launch GodMode9, press the HOME button, select Scripts, and select "DumpKeys" from the list of scripts that appears.
|
||||||
3. Wait for the script to complete and return you to the GodMode9 main menu.
|
3. Wait for the script to complete and return you to the GodMode9 main menu.
|
||||||
4. Power off your system and copy the "gm9/aes_keys.txt" and "gm9/seeddb.bin" files off of your SD card into "(Citra directory)/sysdata/".
|
4. Power off your system and copy the "gm9/aes_keys.txt" file off of your SD card into "(Citra directory)/sysdata/".
|
||||||
|
|
||||||
|
|
2
dist/installer/CMakeLists.txt
vendored
2
dist/installer/CMakeLists.txt
vendored
|
@ -13,8 +13,6 @@ set(BUILD_DIR "${CMAKE_BINARY_DIR}/installer")
|
||||||
set(DIST_DIR "${BUILD_DIR}/dist")
|
set(DIST_DIR "${BUILD_DIR}/dist")
|
||||||
set(TARGET_FILE "${DIST_DIR}/citra-setup-${PLATFORM}")
|
set(TARGET_FILE "${DIST_DIR}/citra-setup-${PLATFORM}")
|
||||||
|
|
||||||
file(MAKE_DIRECTORY "${BUILD_DIR}" "${DIST_DIR}")
|
|
||||||
|
|
||||||
# Adds a custom target that will run the BuildInstaller.cmake file
|
# Adds a custom target that will run the BuildInstaller.cmake file
|
||||||
# CMake can't just run a cmake function as a custom command, so this is a way around it.
|
# CMake can't just run a cmake function as a custom command, so this is a way around it.
|
||||||
# Calls the cmake command and runs a cmake file in "scripting" mode passing in variables with -D
|
# Calls the cmake command and runs a cmake file in "scripting" mode passing in variables with -D
|
||||||
|
|
5
dist/languages/.tx/config
vendored
5
dist/languages/.tx/config
vendored
|
@ -7,8 +7,3 @@ source_file = en.ts
|
||||||
source_lang = en
|
source_lang = en
|
||||||
type = QT
|
type = QT
|
||||||
|
|
||||||
[o:citra:p:citra:r:android]
|
|
||||||
file_filter = ../../src/android/app/src/main/res/values-<lang>/strings.xml
|
|
||||||
source_file = ../../src/android/app/src/main/res/values/strings.xml
|
|
||||||
type = ANDROID
|
|
||||||
lang_map = es_ES:es, hu_HU:hu, ru_RU:ru, pt_BR:pt, zh_CN:zh
|
|
||||||
|
|
3539
dist/languages/da_DK.ts
vendored
3539
dist/languages/da_DK.ts
vendored
File diff suppressed because it is too large
Load diff
3835
dist/languages/de.ts
vendored
3835
dist/languages/de.ts
vendored
File diff suppressed because it is too large
Load diff
3633
dist/languages/el.ts
vendored
3633
dist/languages/el.ts
vendored
File diff suppressed because it is too large
Load diff
3414
dist/languages/es_ES.ts
vendored
3414
dist/languages/es_ES.ts
vendored
File diff suppressed because it is too large
Load diff
3398
dist/languages/fi.ts
vendored
3398
dist/languages/fi.ts
vendored
File diff suppressed because it is too large
Load diff
5293
dist/languages/hu_HU.ts → dist/languages/fi_FI.ts
vendored
5293
dist/languages/hu_HU.ts → dist/languages/fi_FI.ts
vendored
File diff suppressed because it is too large
Load diff
3682
dist/languages/fr.ts
vendored
3682
dist/languages/fr.ts
vendored
File diff suppressed because it is too large
Load diff
3539
dist/languages/id.ts
vendored
3539
dist/languages/id.ts
vendored
File diff suppressed because it is too large
Load diff
3584
dist/languages/it.ts
vendored
3584
dist/languages/it.ts
vendored
File diff suppressed because it is too large
Load diff
3610
dist/languages/ja_JP.ts
vendored
3610
dist/languages/ja_JP.ts
vendored
File diff suppressed because it is too large
Load diff
3634
dist/languages/ko_KR.ts
vendored
3634
dist/languages/ko_KR.ts
vendored
File diff suppressed because it is too large
Load diff
3535
dist/languages/lt_LT.ts
vendored
3535
dist/languages/lt_LT.ts
vendored
File diff suppressed because it is too large
Load diff
3555
dist/languages/nb.ts
vendored
3555
dist/languages/nb.ts
vendored
File diff suppressed because it is too large
Load diff
4279
dist/languages/nl.ts
vendored
4279
dist/languages/nl.ts
vendored
File diff suppressed because it is too large
Load diff
3542
dist/languages/pl_PL.ts
vendored
3542
dist/languages/pl_PL.ts
vendored
File diff suppressed because it is too large
Load diff
3636
dist/languages/pt_BR.ts
vendored
3636
dist/languages/pt_BR.ts
vendored
File diff suppressed because it is too large
Load diff
3572
dist/languages/ro_RO.ts
vendored
3572
dist/languages/ro_RO.ts
vendored
File diff suppressed because it is too large
Load diff
3557
dist/languages/ru_RU.ts
vendored
3557
dist/languages/ru_RU.ts
vendored
File diff suppressed because it is too large
Load diff
3566
dist/languages/tr_TR.ts
vendored
3566
dist/languages/tr_TR.ts
vendored
File diff suppressed because it is too large
Load diff
3697
dist/languages/vi_VN.ts
vendored
3697
dist/languages/vi_VN.ts
vendored
File diff suppressed because it is too large
Load diff
3432
dist/languages/zh_CN.ts
vendored
3432
dist/languages/zh_CN.ts
vendored
File diff suppressed because it is too large
Load diff
3755
dist/languages/zh_TW.ts
vendored
3755
dist/languages/zh_TW.ts
vendored
File diff suppressed because it is too large
Load diff
|
@ -2,13 +2,7 @@
|
||||||
Name=colorful_dark
|
Name=colorful_dark
|
||||||
Comment=Colorful theme (Dark style)
|
Comment=Colorful theme (Dark style)
|
||||||
Inherits=default
|
Inherits=default
|
||||||
Directories=16x16,48x48,256x256
|
Directories=16x16
|
||||||
|
|
||||||
[16x16]
|
[16x16]
|
||||||
Size=16
|
Size=16
|
||||||
|
|
||||||
[48x48]
|
|
||||||
Size=48
|
|
||||||
|
|
||||||
[256x256]
|
|
||||||
Size=256
|
|
||||||
|
|
|
@ -2,13 +2,7 @@
|
||||||
Name=colorful_midnight_blue
|
Name=colorful_midnight_blue
|
||||||
Comment=Colorful theme (Midnight Blue style)
|
Comment=Colorful theme (Midnight Blue style)
|
||||||
Inherits=default
|
Inherits=default
|
||||||
Directories=16x16,48x48,256x256
|
Directories=16x16
|
||||||
|
|
||||||
[16x16]
|
[16x16]
|
||||||
Size=16
|
Size=16
|
||||||
|
|
||||||
[48x48]
|
|
||||||
Size=48
|
|
||||||
|
|
||||||
[256x256]
|
|
||||||
Size=256
|
|
||||||
|
|
18
dist/qt_themes/default/style.qss
vendored
18
dist/qt_themes/default/style.qss
vendored
|
@ -12,23 +12,17 @@ QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton {
|
QPushButton#3DOptionStatusBarButton {
|
||||||
color: #959595;
|
color: #A5A5A5;
|
||||||
|
font-weight: bold;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 0px 3px 0px 3px;
|
padding: 0px 3px 0px 3px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
min-width: 60px;
|
||||||
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton:checked {
|
QPushButton#3DOptionStatusBarButton:hover {
|
||||||
color: #00FF00;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton:hover {
|
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#button_reset_defaults {
|
|
||||||
min-width: 57px;
|
|
||||||
padding: 4px 8px;
|
|
||||||
}
|
|
||||||
|
|
38
dist/qt_themes/qdarkstyle/style.qss
vendored
38
dist/qt_themes/qdarkstyle/style.qss
vendored
|
@ -1,3 +1,19 @@
|
||||||
|
QPushButton#TogglableStatusBarButton {
|
||||||
|
color: #959595;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 0px 3px 0px 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:checked {
|
||||||
|
color: palette(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPushButton#TogglableStatusBarButton:hover {
|
||||||
|
border: 1px solid #76797C;
|
||||||
|
}
|
||||||
|
|
||||||
QPushButton#GraphicsAPIStatusBarButton {
|
QPushButton#GraphicsAPIStatusBarButton {
|
||||||
color: #656565;
|
color: #656565;
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
|
@ -10,23 +26,6 @@ QPushButton#GraphicsAPIStatusBarButton:hover {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton {
|
|
||||||
min-width: 0px;
|
|
||||||
color: #656565;
|
|
||||||
border: 1px solid transparent;
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 0px 3px 0px 3px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton:checked {
|
|
||||||
color: #00FF00;
|
|
||||||
}
|
|
||||||
|
|
||||||
QPushButton#TogglableStatusBarButton:hover {
|
|
||||||
border: 1px solid #76797C;
|
|
||||||
}
|
|
||||||
|
|
||||||
QToolTip {
|
QToolTip {
|
||||||
border: 1px solid #76797C;
|
border: 1px solid #76797C;
|
||||||
background-color: #5A7566;
|
background-color: #5A7566;
|
||||||
|
@ -299,11 +298,6 @@ QAbstractItemView:read-only {
|
||||||
alternate-background-color: #232629;
|
alternate-background-color: #232629;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
|
||||||
QAbstractItemView:item {
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget:focus {
|
QWidget:focus {
|
||||||
border: 1px solid #3daee9;
|
border: 1px solid #3daee9;
|
||||||
}
|
}
|
||||||
|
|
|
@ -481,11 +481,6 @@ QAbstractItemView QLineEdit {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Workaround for https://bugreports.qt.io/browse/QTBUG-115529 */
|
|
||||||
QAbstractItemView:item {
|
|
||||||
border: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* QAbstractScrollArea ----------------------------------------------------
|
/* QAbstractScrollArea ----------------------------------------------------
|
||||||
|
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qabstractscrollarea
|
||||||
|
@ -1072,10 +1067,6 @@ QPushButton:focus {
|
||||||
border: 1px solid #1464A0;
|
border: 1px solid #1464A0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPushButton#button_reset_defaults {
|
|
||||||
padding: 3px 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* QToolButton ------------------------------------------------------------
|
/* QToolButton ------------------------------------------------------------
|
||||||
|
|
||||||
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
|
https://doc.qt.io/qt-5/stylesheet-examples.html#customizing-qtoolbutton
|
||||||
|
|
459
externals/CMakeLists.txt
vendored
459
externals/CMakeLists.txt
vendored
|
@ -4,7 +4,7 @@
|
||||||
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
|
||||||
add_compile_options(/W0)
|
add_compile_options(/W0)
|
||||||
else()
|
else()
|
||||||
add_compile_options(-w)
|
add_compile_options(-Wno-error)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules)
|
||||||
|
@ -12,62 +12,58 @@ include(DownloadExternals)
|
||||||
include(ExternalProject)
|
include(ExternalProject)
|
||||||
|
|
||||||
# Boost
|
# Boost
|
||||||
if (NOT USE_SYSTEM_BOOST)
|
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost")
|
||||||
message(STATUS "Including vendored Boost library")
|
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost")
|
||||||
set(BOOST_ROOT "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
set(Boost_NO_SYSTEM_PATHS ON)
|
||||||
set(Boost_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/externals/boost" CACHE STRING "")
|
add_library(boost INTERFACE)
|
||||||
set(Boost_NO_SYSTEM_PATHS ON CACHE BOOL "")
|
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
||||||
add_library(boost INTERFACE)
|
|
||||||
target_include_directories(boost SYSTEM INTERFACE ${Boost_INCLUDE_DIR})
|
|
||||||
|
|
||||||
# Boost::serialization
|
# Boost::serialization
|
||||||
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
file(GLOB boost_serialization_SRC "${CMAKE_SOURCE_DIR}/externals/boost/libs/serialization/src/*.cpp")
|
||||||
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
add_library(boost_serialization STATIC ${boost_serialization_SRC})
|
||||||
target_link_libraries(boost_serialization PUBLIC boost)
|
target_link_libraries(boost_serialization PUBLIC boost)
|
||||||
|
|
||||||
|
# Boost::iostreams
|
||||||
|
add_library(
|
||||||
|
boost_iostreams
|
||||||
|
STATIC
|
||||||
|
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(boost_iostreams PUBLIC boost)
|
||||||
|
|
||||||
# Boost::iostreams
|
|
||||||
add_library(
|
|
||||||
boost_iostreams
|
|
||||||
STATIC
|
|
||||||
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/file_descriptor.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/externals/boost/libs/iostreams/src/mapped_file.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(boost_iostreams PUBLIC boost)
|
|
||||||
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
# Add additional boost libs here; remember to ALIAS them in the root CMakeLists!
|
||||||
else()
|
|
||||||
unset(BOOST_ROOT CACHE)
|
|
||||||
unset(Boost_INCLUDE_DIR CACHE)
|
|
||||||
set(Boost_NO_SYSTEM_PATHS OFF CACHE BOOL "" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Catch2
|
# Catch2
|
||||||
add_library(catch2 INTERFACE)
|
set(CATCH_INSTALL_DOCS OFF)
|
||||||
if(USE_SYSTEM_CATCH2)
|
set(CATCH_INSTALL_EXTRAS OFF)
|
||||||
find_package(Catch2 3.0.0 REQUIRED)
|
add_subdirectory(catch2)
|
||||||
else()
|
|
||||||
set(CATCH_INSTALL_DOCS OFF CACHE BOOL "")
|
|
||||||
set(CATCH_INSTALL_EXTRAS OFF CACHE BOOL "")
|
|
||||||
add_subdirectory(catch2)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(catch2 INTERFACE Catch2::Catch2WithMain)
|
|
||||||
|
|
||||||
# Crypto++
|
# Crypto++
|
||||||
if(USE_SYSTEM_CRYPTOPP)
|
set(CRYPTOPP_BUILD_DOCUMENTATION OFF)
|
||||||
find_package(cryptopp REQUIRED)
|
set(CRYPTOPP_BUILD_TESTING OFF)
|
||||||
add_library(cryptopp INTERFACE)
|
set(CRYPTOPP_INSTALL OFF)
|
||||||
target_link_libraries(cryptopp INTERFACE cryptopp::cryptopp)
|
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp")
|
||||||
else()
|
add_subdirectory(cryptopp-cmake)
|
||||||
if (WIN32 AND NOT MSVC AND "arm64" IN_LIST ARCHITECTURE)
|
|
||||||
# TODO: CryptoPP ARM64 ASM does not seem to support Windows unless compiled with MSVC.
|
|
||||||
# TODO: See https://github.com/weidai11/cryptopp/issues/1260
|
|
||||||
set(CRYPTOPP_DISABLE_ASM ON CACHE BOOL "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CRYPTOPP_BUILD_DOCUMENTATION OFF CACHE BOOL "")
|
# HACK: Mismatch between compilation of CryptoPP and headers used in Citra can cause runtime issues.
|
||||||
set(CRYPTOPP_BUILD_TESTING OFF CACHE BOOL "")
|
# Pull out the compile definitions from CryptoPP and apply them to Citra as well to fix this.
|
||||||
set(CRYPTOPP_INSTALL OFF CACHE BOOL "")
|
# See: https://github.com/weidai11/cryptopp/issues/1191
|
||||||
set(CRYPTOPP_SOURCES "${CMAKE_SOURCE_DIR}/externals/cryptopp" CACHE STRING "")
|
get_source_file_property(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_SOURCES}/cryptlib.cpp TARGET_DIRECTORY cryptopp COMPILE_DEFINITIONS)
|
||||||
add_subdirectory(cryptopp-cmake)
|
set(CRYPTOPP_COMPILE_DEFINITIONS ${CRYPTOPP_COMPILE_DEFINITIONS} PARENT_SCOPE)
|
||||||
|
|
||||||
|
# HACK: The logic to set up the base include directory for CryptoPP does not work with Android SDK CMake 3.22.1.
|
||||||
|
# Until there is a fixed version available, this code will detect and add in the proper include if it does not exist.
|
||||||
|
if(ANDROID)
|
||||||
|
message(STATUS "Applying CryptoPP include fix.")
|
||||||
|
get_target_property(CRYPTOPP_INCLUDES cryptopp INTERFACE_INCLUDE_DIRECTORIES)
|
||||||
|
foreach(CRYPTOPP_INCLUDE ${CRYPTOPP_INCLUDES})
|
||||||
|
if("${CRYPTOPP_INCLUDE}" MATCHES "\\$<BUILD_INTERFACE:(.*)/cryptopp>")
|
||||||
|
message(STATUS "Fixed include path: ${CMAKE_MATCH_1}")
|
||||||
|
target_include_directories(cryptopp PUBLIC $<BUILD_INTERFACE:${CMAKE_MATCH_1}>)
|
||||||
|
break()
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# dds-ktx
|
# dds-ktx
|
||||||
|
@ -76,49 +72,19 @@ target_include_directories(dds-ktx INTERFACE ./dds-ktx)
|
||||||
|
|
||||||
# fmt and Xbyak need to be added before dynarmic
|
# fmt and Xbyak need to be added before dynarmic
|
||||||
# libfmt
|
# libfmt
|
||||||
if(USE_SYSTEM_FMT)
|
option(FMT_INSTALL "" ON)
|
||||||
add_library(fmt INTERFACE)
|
add_subdirectory(fmt EXCLUDE_FROM_ALL)
|
||||||
find_package(fmt REQUIRED)
|
|
||||||
target_link_libraries(fmt INTERFACE fmt::fmt)
|
|
||||||
else()
|
|
||||||
option(FMT_INSTALL "" ON)
|
|
||||||
add_subdirectory(fmt EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# Xbyak
|
# Xbyak
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE)
|
||||||
if(USE_SYSTEM_XBYAK)
|
add_subdirectory(xbyak EXCLUDE_FROM_ALL)
|
||||||
find_package(xbyak REQUIRED)
|
|
||||||
add_library(xbyak INTERFACE)
|
|
||||||
target_link_libraries(xbyak INTERFACE xbyak::xbyak)
|
|
||||||
else()
|
|
||||||
add_subdirectory(xbyak EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Oaknut
|
|
||||||
if ("arm64" IN_LIST ARCHITECTURE)
|
|
||||||
add_subdirectory(oaknut EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Dynarmic
|
# Dynarmic
|
||||||
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
if ("x86_64" IN_LIST ARCHITECTURE OR "arm64" IN_LIST ARCHITECTURE)
|
||||||
if(USE_SYSTEM_DYNARMIC)
|
set(DYNARMIC_TESTS OFF)
|
||||||
find_package(dynarmic REQUIRED)
|
set(DYNARMIC_FRONTENDS "A32")
|
||||||
add_library(dynarmic INTERFACE)
|
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
|
||||||
target_link_libraries(dynarmic INTERFACE dynarmic::dynarmic)
|
|
||||||
# The dynarmic package's cmake files are helpfully completely silent
|
|
||||||
# so we have to inform the user of its status ourselves
|
|
||||||
if(TARGET dynarmic::dynarmic)
|
|
||||||
message(STATUS "Found dynarmic")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(DYNARMIC_TESTS OFF CACHE BOOL "")
|
|
||||||
set(DYNARMIC_FRONTENDS "A32" CACHE STRING "")
|
|
||||||
set(DYNARMIC_USE_PRECOMPILED_HEADERS ${CITRA_USE_PRECOMPILED_HEADERS} CACHE BOOL "")
|
|
||||||
add_subdirectory(dynarmic EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# getopt
|
# getopt
|
||||||
|
@ -126,59 +92,46 @@ if (MSVC)
|
||||||
add_subdirectory(getopt)
|
add_subdirectory(getopt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Glad
|
||||||
|
add_subdirectory(glad)
|
||||||
|
|
||||||
|
# glslang
|
||||||
|
set(SKIP_GLSLANG_INSTALL ON)
|
||||||
|
set(ENABLE_GLSLANG_BINARIES OFF)
|
||||||
|
set(ENABLE_SPVREMAPPER OFF)
|
||||||
|
set(ENABLE_CTEST OFF)
|
||||||
|
add_subdirectory(glslang)
|
||||||
|
|
||||||
# inih
|
# inih
|
||||||
if(USE_SYSTEM_INIH)
|
add_subdirectory(inih)
|
||||||
find_package(inih REQUIRED COMPONENTS inih inir)
|
|
||||||
add_library(inih INTERFACE)
|
|
||||||
target_link_libraries(inih INTERFACE inih::inih inih::inir)
|
|
||||||
else()
|
|
||||||
add_subdirectory(inih)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# MicroProfile
|
# MicroProfile
|
||||||
add_library(microprofile INTERFACE)
|
add_library(microprofile INTERFACE)
|
||||||
target_include_directories(microprofile SYSTEM INTERFACE ./microprofile)
|
target_include_directories(microprofile INTERFACE ./microprofile)
|
||||||
|
|
||||||
# Nihstro
|
# Nihstro
|
||||||
add_library(nihstro-headers INTERFACE)
|
add_library(nihstro-headers INTERFACE)
|
||||||
target_include_directories(nihstro-headers SYSTEM INTERFACE ./nihstro/include)
|
target_include_directories(nihstro-headers INTERFACE ./nihstro/include)
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
# TODO: For some reason MSVC still applies this warning even with /W0 for externals.
|
target_compile_options(nihstro-headers INTERFACE /W0)
|
||||||
target_compile_options(nihstro-headers INTERFACE /wd4715)
|
else()
|
||||||
|
target_compile_options(nihstro-headers INTERFACE -Wno-error)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Open Source Archives
|
# Open Source Archives
|
||||||
add_subdirectory(open_source_archives)
|
add_subdirectory(open_source_archives)
|
||||||
|
|
||||||
# faad2
|
|
||||||
add_subdirectory(faad2 EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
# Dynamic library headers
|
# Dynamic library headers
|
||||||
add_library(library-headers INTERFACE)
|
add_subdirectory(library-headers EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
if (USE_SYSTEM_FFMPEG_HEADERS)
|
|
||||||
find_path(SYSTEM_FFMPEG_INCLUDES NAMES libavutil/avutil.h)
|
|
||||||
if (SYSTEM_FFMPEG_INCLUDES STREQUAL "SYSTEM_FFMPEG_INCLUDES-NOTFOUND")
|
|
||||||
message(WARNING "System FFmpeg headers not found. Falling back on bundled headers.")
|
|
||||||
else()
|
|
||||||
message(STATUS "Using system FFmpeg headers.")
|
|
||||||
target_include_directories(library-headers SYSTEM INTERFACE ${SYSTEM_FFMPEG_INCLUDES})
|
|
||||||
set(FOUND_FFMPEG_HEADERS ON)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if (NOT FOUND_FFMPEG_HEADERS)
|
|
||||||
message(STATUS "Using bundled ffmpeg headers.")
|
|
||||||
target_include_directories(library-headers SYSTEM INTERFACE ./library-headers/ffmpeg/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# SoundTouch
|
# SoundTouch
|
||||||
if(NOT USE_SYSTEM_SOUNDTOUCH)
|
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
||||||
set(INTEGER_SAMPLES ON CACHE BOOL "")
|
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
||||||
set(SOUNDSTRETCH OFF CACHE BOOL "")
|
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
||||||
set(SOUNDTOUCH_DLL OFF CACHE BOOL "")
|
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
||||||
add_subdirectory(soundtouch EXCLUDE_FROM_ALL)
|
|
||||||
target_compile_definitions(SoundTouch PUBLIC SOUNDTOUCH_INTEGER_SAMPLES)
|
# sirit
|
||||||
endif()
|
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
# Teakra
|
# Teakra
|
||||||
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
add_subdirectory(teakra EXCLUDE_FROM_ALL)
|
||||||
|
@ -188,158 +141,78 @@ if (ENABLE_SDL2 AND NOT USE_SYSTEM_SDL2)
|
||||||
add_subdirectory(sdl2)
|
add_subdirectory(sdl2)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# libusb
|
|
||||||
if (ENABLE_LIBUSB AND NOT USE_SYSTEM_LIBUSB)
|
|
||||||
add_subdirectory(libusb)
|
|
||||||
set(LIBUSB_INCLUDE_DIR "" PARENT_SCOPE)
|
|
||||||
set(LIBUSB_LIBRARIES usb PARENT_SCOPE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Zstandard
|
# Zstandard
|
||||||
if(USE_SYSTEM_ZSTD)
|
set(ZSTD_LEGACY_SUPPORT OFF)
|
||||||
find_package(zstd REQUIRED)
|
set(ZSTD_BUILD_PROGRAMS OFF)
|
||||||
add_library(zstd INTERFACE)
|
set(ZSTD_BUILD_SHARED OFF)
|
||||||
if(TARGET zstd::libzstd_shared)
|
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
||||||
message(STATUS "Found system Zstandard")
|
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/externals/zstd/lib>)
|
||||||
endif()
|
|
||||||
target_link_libraries(zstd INTERFACE zstd::libzstd_shared)
|
|
||||||
else()
|
|
||||||
set(ZSTD_LEGACY_SUPPORT OFF)
|
|
||||||
set(ZSTD_BUILD_PROGRAMS OFF)
|
|
||||||
set(ZSTD_BUILD_SHARED OFF)
|
|
||||||
add_subdirectory(zstd/build/cmake EXCLUDE_FROM_ALL)
|
|
||||||
target_include_directories(libzstd_static INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/externals/zstd/lib>)
|
|
||||||
add_library(zstd ALIAS libzstd_static)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# ENet
|
# ENet
|
||||||
if(USE_SYSTEM_ENET)
|
add_subdirectory(enet)
|
||||||
find_package(libenet REQUIRED)
|
target_include_directories(enet INTERFACE ./enet/include)
|
||||||
add_library(enet INTERFACE)
|
|
||||||
target_link_libraries(enet INTERFACE libenet::libenet)
|
|
||||||
else()
|
|
||||||
add_subdirectory(enet)
|
|
||||||
target_include_directories(enet INTERFACE ./enet/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Cubeb
|
# Cubeb
|
||||||
if (ENABLE_CUBEB)
|
if (ENABLE_CUBEB)
|
||||||
if(USE_SYSTEM_CUBEB)
|
set(BUILD_TESTS OFF CACHE BOOL "")
|
||||||
find_package(cubeb REQUIRED)
|
set(BUILD_TOOLS OFF CACHE BOOL "")
|
||||||
add_library(cubeb INTERFACE)
|
set(BUNDLE_SPEEX ON CACHE BOOL "")
|
||||||
target_link_libraries(cubeb INTERFACE cubeb::cubeb)
|
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
||||||
if(TARGET cubeb::cubeb)
|
|
||||||
message(STATUS "Found system cubeb")
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
set(BUILD_TESTS OFF CACHE BOOL "")
|
|
||||||
set(BUILD_TOOLS OFF CACHE BOOL "")
|
|
||||||
set(BUNDLE_SPEEX ON CACHE BOOL "")
|
|
||||||
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# DiscordRPC
|
# DiscordRPC
|
||||||
if (USE_DISCORD_PRESENCE)
|
if (USE_DISCORD_PRESENCE)
|
||||||
# rapidjson used by discord-rpc is old and doesn't correctly detect endianness for some platforms.
|
|
||||||
include(TestBigEndian)
|
|
||||||
test_big_endian(RAPIDJSON_BIG_ENDIAN)
|
|
||||||
if(RAPIDJSON_BIG_ENDIAN)
|
|
||||||
add_compile_definitions(RAPIDJSON_ENDIAN=1)
|
|
||||||
else()
|
|
||||||
add_compile_definitions(RAPIDJSON_ENDIAN=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Apply a dummy CLANG_FORMAT_SUFFIX to disable discord-rpc's unnecessary automatic clang-format.
|
|
||||||
set(CLANG_FORMAT_SUFFIX "dummy")
|
|
||||||
|
|
||||||
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
|
add_subdirectory(discord-rpc EXCLUDE_FROM_ALL)
|
||||||
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# JSON
|
# JSON
|
||||||
add_library(json-headers INTERFACE)
|
add_library(json-headers INTERFACE)
|
||||||
if (USE_SYSTEM_JSON)
|
target_include_directories(json-headers INTERFACE ./json)
|
||||||
find_package(nlohmann_json REQUIRED)
|
|
||||||
target_link_libraries(json-headers INTERFACE nlohmann_json::nlohmann_json)
|
|
||||||
get_target_property(NLOHMANN_PREFIX nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
|
|
||||||
# The nlohmann-json3 package expects "#include <nlohmann/json.hpp>"
|
|
||||||
# Citra uses "#include <json.hpp>" so we have to add this manually
|
|
||||||
target_include_directories(json-headers SYSTEM INTERFACE "${NLOHMANN_PREFIX}/nlohmann")
|
|
||||||
else()
|
|
||||||
target_include_directories(json-headers SYSTEM INTERFACE ./json)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# OpenSSL
|
if (ENABLE_WEB_SERVICE)
|
||||||
if (USE_SYSTEM_OPENSSL)
|
if (USE_SYSTEM_OPENSSL)
|
||||||
find_package(OpenSSL 1.1)
|
find_package(OpenSSL 1.1)
|
||||||
if (OPENSSL_FOUND)
|
if (OPENSSL_FOUND)
|
||||||
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
set(OPENSSL_LIBRARIES OpenSSL::SSL OpenSSL::Crypto)
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT OPENSSL_FOUND)
|
|
||||||
# LibreSSL
|
|
||||||
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
|
||||||
set(OPENSSLDIR "/etc/ssl/")
|
|
||||||
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
|
||||||
target_include_directories(ssl SYSTEM INTERFACE ./libressl/include)
|
|
||||||
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
|
||||||
get_directory_property(OPENSSL_LIBRARIES
|
|
||||||
DIRECTORY libressl
|
|
||||||
DEFINITION OPENSSL_LIBS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# httplib
|
|
||||||
add_library(httplib INTERFACE)
|
|
||||||
if(USE_SYSTEM_CPP_HTTPLIB)
|
|
||||||
find_package(CppHttp 0.14.1)
|
|
||||||
# Detect if system cpphttplib is a shared library
|
|
||||||
# this breaks building as Citra relies on functions that are moved
|
|
||||||
# into the shared object.
|
|
||||||
get_target_property(HTTP_LIBS httplib::httplib INTERFACE_LINK_LIBRARIES)
|
|
||||||
if(HTTP_LIBS)
|
|
||||||
message(WARNING "Shared cpp-http (${HTTP_LIBS}) not supported. Falling back to bundled...")
|
|
||||||
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
|
||||||
else()
|
|
||||||
if(CppHttp_FOUND)
|
|
||||||
target_link_libraries(httplib INTERFACE httplib::httplib)
|
|
||||||
else()
|
|
||||||
message(STATUS "Cpp-httplib not found or not suitable version! Falling back to bundled...")
|
|
||||||
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
else()
|
|
||||||
target_include_directories(httplib SYSTEM INTERFACE ./httplib)
|
|
||||||
endif()
|
|
||||||
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
|
||||||
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE)
|
if (NOT OPENSSL_FOUND)
|
||||||
add_subdirectory(gamemode)
|
# LibreSSL
|
||||||
endif()
|
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
||||||
|
set(OPENSSLDIR "/etc/ssl/")
|
||||||
|
add_subdirectory(libressl EXCLUDE_FROM_ALL)
|
||||||
|
target_include_directories(ssl INTERFACE ./libressl/include)
|
||||||
|
target_compile_definitions(ssl PRIVATE -DHAVE_INET_NTOP)
|
||||||
|
get_directory_property(OPENSSL_LIBRARIES
|
||||||
|
DIRECTORY libressl
|
||||||
|
DEFINITION OPENSSL_LIBS)
|
||||||
|
endif()
|
||||||
|
|
||||||
# cpp-jwt
|
if(ANDROID)
|
||||||
if (ENABLE_WEB_SERVICE)
|
add_subdirectory(android-ifaddrs)
|
||||||
if (USE_SYSTEM_CPP_JWT)
|
endif()
|
||||||
find_package(cpp-jwt REQUIRED)
|
|
||||||
add_library(cpp-jwt INTERFACE)
|
# httplib
|
||||||
target_link_libraries(cpp-jwt INTERFACE cpp-jwt::cpp-jwt)
|
add_library(httplib INTERFACE)
|
||||||
|
target_include_directories(httplib INTERFACE ./httplib)
|
||||||
|
target_compile_options(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||||
|
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
||||||
|
|
||||||
|
# cpp-jwt
|
||||||
|
add_library(cpp-jwt INTERFACE)
|
||||||
|
target_include_directories(cpp-jwt INTERFACE ./cpp-jwt/include)
|
||||||
|
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
||||||
|
if (MSVC)
|
||||||
|
target_compile_options(cpp-jwt INTERFACE /W0)
|
||||||
else()
|
else()
|
||||||
add_library(cpp-jwt INTERFACE)
|
target_compile_options(cpp-jwt INTERFACE -Wno-error)
|
||||||
target_include_directories(cpp-jwt SYSTEM INTERFACE ./cpp-jwt/include)
|
|
||||||
target_compile_definitions(cpp-jwt INTERFACE CPP_JWT_USE_VENDORED_NLOHMANN_JSON)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# lodepng
|
# lodepng
|
||||||
if(USE_SYSTEM_LODEPNG)
|
add_subdirectory(lodepng)
|
||||||
add_library(lodepng INTERFACE)
|
|
||||||
find_package(lodepng REQUIRED)
|
|
||||||
target_link_libraries(lodepng INTERFACE lodepng::lodepng)
|
|
||||||
else()
|
|
||||||
add_subdirectory(lodepng)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# (xperia64): Only use libyuv on Android b/c of build issues on Windows and mandatory JPEG
|
# (xperia64): Only use libyuv on Android b/c of build issues on Windows and mandatory JPEG
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
|
@ -350,81 +223,21 @@ endif()
|
||||||
|
|
||||||
# OpenAL Soft
|
# OpenAL Soft
|
||||||
if (ENABLE_OPENAL)
|
if (ENABLE_OPENAL)
|
||||||
if(USE_SYSTEM_OPENAL)
|
set(ALSOFT_EMBED_HRTF_DATA OFF CACHE BOOL "")
|
||||||
add_library(OpenAL INTERFACE)
|
set(ALSOFT_EXAMPLES OFF CACHE BOOL "")
|
||||||
find_package(OpenAL REQUIRED)
|
set(ALSOFT_INSTALL OFF CACHE BOOL "")
|
||||||
target_link_libraries(OpenAL INTERFACE OpenAL::OpenAL)
|
set(ALSOFT_INSTALL_CONFIG OFF CACHE BOOL "")
|
||||||
else()
|
set(ALSOFT_INSTALL_HRTF_DATA OFF CACHE BOOL "")
|
||||||
set(ALSOFT_EMBED_HRTF_DATA OFF CACHE BOOL "")
|
set(ALSOFT_INSTALL_AMBDEC_PRESETS OFF CACHE BOOL "")
|
||||||
set(ALSOFT_EXAMPLES OFF CACHE BOOL "")
|
set(ALSOFT_UTILS OFF CACHE BOOL "")
|
||||||
set(ALSOFT_INSTALL OFF CACHE BOOL "")
|
set(LIBTYPE "STATIC" CACHE STRING "")
|
||||||
set(ALSOFT_INSTALL_CONFIG OFF CACHE BOOL "")
|
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
||||||
set(ALSOFT_INSTALL_HRTF_DATA OFF CACHE BOOL "")
|
|
||||||
set(ALSOFT_INSTALL_AMBDEC_PRESETS OFF CACHE BOOL "")
|
|
||||||
set(ALSOFT_UTILS OFF CACHE BOOL "")
|
|
||||||
set(LIBTYPE "STATIC" CACHE STRING "")
|
|
||||||
add_subdirectory(openal-soft EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenGL dependencies
|
# VMA
|
||||||
if (ENABLE_OPENGL)
|
add_library(vma INTERFACE)
|
||||||
# Glad
|
target_include_directories(vma INTERFACE ./vma/include)
|
||||||
add_subdirectory(glad)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Vulkan dependencies
|
# vulkan-headers
|
||||||
if (ENABLE_VULKAN)
|
add_library(vulkan-headers INTERFACE)
|
||||||
# glslang
|
target_include_directories(vulkan-headers INTERFACE ./vulkan-headers/include)
|
||||||
if(USE_SYSTEM_GLSLANG)
|
|
||||||
find_package(glslang REQUIRED)
|
|
||||||
add_library(glslang INTERFACE)
|
|
||||||
add_library(SPIRV INTERFACE)
|
|
||||||
target_link_libraries(glslang INTERFACE glslang::glslang)
|
|
||||||
target_link_libraries(SPIRV INTERFACE glslang::SPIRV)
|
|
||||||
# System include path is different from submodule include path
|
|
||||||
get_target_property(GLSLANG_PREFIX glslang::SPIRV INTERFACE_INCLUDE_DIRECTORIES)
|
|
||||||
target_include_directories(SPIRV SYSTEM INTERFACE "${GLSLANG_PREFIX}/glslang")
|
|
||||||
else()
|
|
||||||
set(SKIP_GLSLANG_INSTALL ON CACHE BOOL "")
|
|
||||||
set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "")
|
|
||||||
set(ENABLE_SPVREMAPPER OFF CACHE BOOL "")
|
|
||||||
set(ENABLE_CTEST OFF CACHE BOOL "")
|
|
||||||
set(ENABLE_HLSL OFF CACHE BOOL "")
|
|
||||||
set(BUILD_EXTERNAL OFF CACHE BOOL "")
|
|
||||||
add_subdirectory(glslang)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# sirit
|
|
||||||
add_subdirectory(sirit EXCLUDE_FROM_ALL)
|
|
||||||
|
|
||||||
# VMA
|
|
||||||
if(USE_SYSTEM_VMA)
|
|
||||||
add_library(vma INTERFACE)
|
|
||||||
find_package(VulkanMemoryAllocator REQUIRED)
|
|
||||||
if(TARGET GPUOpen::VulkanMemoryAllocator)
|
|
||||||
message(STATUS "Found VulkanMemoryAllocator")
|
|
||||||
target_link_libraries(vma INTERFACE GPUOpen::VulkanMemoryAllocator)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
add_library(vma INTERFACE)
|
|
||||||
target_include_directories(vma SYSTEM INTERFACE ./vma/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# vulkan-headers
|
|
||||||
add_library(vulkan-headers INTERFACE)
|
|
||||||
if(USE_SYSTEM_VULKAN_HEADERS)
|
|
||||||
find_package(Vulkan REQUIRED)
|
|
||||||
if(TARGET Vulkan::Headers)
|
|
||||||
message(STATUS "Found Vulkan headers")
|
|
||||||
target_link_libraries(vulkan-headers INTERFACE Vulkan::Headers)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
target_include_directories(vulkan-headers SYSTEM INTERFACE ./vulkan-headers/include)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# adrenotools
|
|
||||||
if (ANDROID AND "arm64" IN_LIST ARCHITECTURE)
|
|
||||||
add_subdirectory(libadrenotools)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
8
externals/android-ifaddrs/CMakeLists.txt
vendored
Normal file
8
externals/android-ifaddrs/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
add_library(ifaddrs
|
||||||
|
ifaddrs.c
|
||||||
|
ifaddrs.h
|
||||||
|
)
|
||||||
|
|
||||||
|
create_target_directory_groups(ifaddrs)
|
||||||
|
|
||||||
|
target_include_directories(ifaddrs INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
600
externals/android-ifaddrs/ifaddrs.c
vendored
Normal file
600
externals/android-ifaddrs/ifaddrs.c
vendored
Normal file
|
@ -0,0 +1,600 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2013, Kenneth MacKay
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ifaddrs.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <net/if_arp.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
|
typedef struct NetlinkList
|
||||||
|
{
|
||||||
|
struct NetlinkList *m_next;
|
||||||
|
struct nlmsghdr *m_data;
|
||||||
|
unsigned int m_size;
|
||||||
|
} NetlinkList;
|
||||||
|
|
||||||
|
static int netlink_socket(void)
|
||||||
|
{
|
||||||
|
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
|
if(l_socket < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_nl l_addr;
|
||||||
|
memset(&l_addr, 0, sizeof(l_addr));
|
||||||
|
l_addr.nl_family = AF_NETLINK;
|
||||||
|
if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
|
||||||
|
{
|
||||||
|
close(l_socket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return l_socket;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netlink_send(int p_socket, int p_request)
|
||||||
|
{
|
||||||
|
char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
|
||||||
|
memset(l_buffer, 0, sizeof(l_buffer));
|
||||||
|
struct nlmsghdr *l_hdr = (struct nlmsghdr *)l_buffer;
|
||||||
|
struct rtgenmsg *l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
|
||||||
|
|
||||||
|
l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
|
||||||
|
l_hdr->nlmsg_type = p_request;
|
||||||
|
l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
|
||||||
|
l_hdr->nlmsg_pid = 0;
|
||||||
|
l_hdr->nlmsg_seq = p_socket;
|
||||||
|
l_msg->rtgen_family = AF_UNSPEC;
|
||||||
|
|
||||||
|
struct sockaddr_nl l_addr;
|
||||||
|
memset(&l_addr, 0, sizeof(l_addr));
|
||||||
|
l_addr.nl_family = AF_NETLINK;
|
||||||
|
return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
|
||||||
|
{
|
||||||
|
struct msghdr l_msg;
|
||||||
|
struct iovec l_iov = { p_buffer, p_len };
|
||||||
|
struct sockaddr_nl l_addr;
|
||||||
|
int l_result;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
l_msg.msg_name = (void *)&l_addr;
|
||||||
|
l_msg.msg_namelen = sizeof(l_addr);
|
||||||
|
l_msg.msg_iov = &l_iov;
|
||||||
|
l_msg.msg_iovlen = 1;
|
||||||
|
l_msg.msg_control = NULL;
|
||||||
|
l_msg.msg_controllen = 0;
|
||||||
|
l_msg.msg_flags = 0;
|
||||||
|
int l_result = recvmsg(p_socket, &l_msg, 0);
|
||||||
|
|
||||||
|
if(l_result < 0)
|
||||||
|
{
|
||||||
|
if(errno == EINTR)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_msg.msg_flags & MSG_TRUNC)
|
||||||
|
{ // buffer was too small
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return l_result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
|
||||||
|
{
|
||||||
|
size_t l_size = 4096;
|
||||||
|
void *l_buffer = NULL;
|
||||||
|
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
free(l_buffer);
|
||||||
|
l_buffer = malloc(l_size);
|
||||||
|
|
||||||
|
int l_read = netlink_recv(p_socket, l_buffer, l_size);
|
||||||
|
*p_size = l_read;
|
||||||
|
if(l_read == -2)
|
||||||
|
{
|
||||||
|
free(l_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(l_read >= 0)
|
||||||
|
{
|
||||||
|
pid_t l_pid = getpid();
|
||||||
|
struct nlmsghdr *l_hdr;
|
||||||
|
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
|
||||||
|
{
|
||||||
|
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
||||||
|
{
|
||||||
|
*p_done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == NLMSG_ERROR)
|
||||||
|
{
|
||||||
|
free(l_buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return l_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
l_size *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
|
||||||
|
{
|
||||||
|
NetlinkList *l_item = malloc(sizeof(NetlinkList));
|
||||||
|
l_item->m_next = NULL;
|
||||||
|
l_item->m_data = p_data;
|
||||||
|
l_item->m_size = p_size;
|
||||||
|
return l_item;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void freeResultList(NetlinkList *p_list)
|
||||||
|
{
|
||||||
|
NetlinkList *l_cur;
|
||||||
|
while(p_list)
|
||||||
|
{
|
||||||
|
l_cur = p_list;
|
||||||
|
p_list = p_list->m_next;
|
||||||
|
free(l_cur->m_data);
|
||||||
|
free(l_cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NetlinkList *getResultList(int p_socket, int p_request)
|
||||||
|
{
|
||||||
|
if(netlink_send(p_socket, p_request) < 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlinkList *l_list = NULL;
|
||||||
|
NetlinkList *l_end = NULL;
|
||||||
|
int l_size;
|
||||||
|
int l_done = 0;
|
||||||
|
while(!l_done)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
|
||||||
|
if(!l_hdr)
|
||||||
|
{ // error
|
||||||
|
freeResultList(l_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlinkList *l_item = newListItem(l_hdr, l_size);
|
||||||
|
if(!l_list)
|
||||||
|
{
|
||||||
|
l_list = l_item;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l_end->m_next = l_item;
|
||||||
|
}
|
||||||
|
l_end = l_item;
|
||||||
|
}
|
||||||
|
return l_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t maxSize(size_t a, size_t b)
|
||||||
|
{
|
||||||
|
return (a > b ? a : b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
|
||||||
|
{
|
||||||
|
switch(p_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
return sizeof(struct sockaddr_in);
|
||||||
|
case AF_INET6:
|
||||||
|
return sizeof(struct sockaddr_in6);
|
||||||
|
case AF_PACKET:
|
||||||
|
return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
|
||||||
|
default:
|
||||||
|
return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
|
||||||
|
{
|
||||||
|
switch(p_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
|
||||||
|
break;
|
||||||
|
case AF_INET6:
|
||||||
|
memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
|
||||||
|
break;
|
||||||
|
case AF_PACKET:
|
||||||
|
memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
|
||||||
|
((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
memcpy(p_dest->sa_data, p_data, p_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
p_dest->sa_family = p_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
|
||||||
|
{
|
||||||
|
if(!*p_resultList)
|
||||||
|
{
|
||||||
|
*p_resultList = p_entry;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct ifaddrs *l_cur = *p_resultList;
|
||||||
|
while(l_cur->ifa_next)
|
||||||
|
{
|
||||||
|
l_cur = l_cur->ifa_next;
|
||||||
|
}
|
||||||
|
l_cur->ifa_next = p_entry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
||||||
|
{
|
||||||
|
struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
|
||||||
|
|
||||||
|
size_t l_nameSize = 0;
|
||||||
|
size_t l_addrSize = 0;
|
||||||
|
size_t l_dataSize = 0;
|
||||||
|
|
||||||
|
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
||||||
|
struct rtattr *l_rta;
|
||||||
|
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
||||||
|
{
|
||||||
|
void *l_rtaData = RTA_DATA(l_rta);
|
||||||
|
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
||||||
|
switch(l_rta->rta_type)
|
||||||
|
{
|
||||||
|
case IFLA_ADDRESS:
|
||||||
|
case IFLA_BROADCAST:
|
||||||
|
l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
|
||||||
|
break;
|
||||||
|
case IFLA_IFNAME:
|
||||||
|
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
||||||
|
break;
|
||||||
|
case IFLA_STATS:
|
||||||
|
l_dataSize += NLMSG_ALIGN(l_rtaSize);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize + l_dataSize);
|
||||||
|
memset(l_entry, 0, sizeof(struct ifaddrs));
|
||||||
|
l_entry->ifa_name = "";
|
||||||
|
|
||||||
|
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
||||||
|
char *l_addr = l_name + l_nameSize;
|
||||||
|
char *l_data = l_addr + l_addrSize;
|
||||||
|
|
||||||
|
l_entry->ifa_flags = l_info->ifi_flags;
|
||||||
|
|
||||||
|
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
|
||||||
|
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifinfomsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
||||||
|
{
|
||||||
|
void *l_rtaData = RTA_DATA(l_rta);
|
||||||
|
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
||||||
|
switch(l_rta->rta_type)
|
||||||
|
{
|
||||||
|
case IFLA_ADDRESS:
|
||||||
|
case IFLA_BROADCAST:
|
||||||
|
{
|
||||||
|
size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
|
||||||
|
makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
||||||
|
((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
|
||||||
|
((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
|
||||||
|
if(l_rta->rta_type == IFLA_ADDRESS)
|
||||||
|
{
|
||||||
|
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
l_addr += NLMSG_ALIGN(l_addrLen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IFLA_IFNAME:
|
||||||
|
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
||||||
|
l_name[l_rtaDataSize] = '\0';
|
||||||
|
l_entry->ifa_name = l_name;
|
||||||
|
break;
|
||||||
|
case IFLA_STATS:
|
||||||
|
memcpy(l_data, l_rtaData, l_rtaDataSize);
|
||||||
|
l_entry->ifa_data = l_data;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addToEnd(p_resultList, l_entry);
|
||||||
|
p_links[l_info->ifi_index - 1] = l_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
||||||
|
{
|
||||||
|
struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
|
||||||
|
|
||||||
|
size_t l_nameSize = 0;
|
||||||
|
size_t l_addrSize = 0;
|
||||||
|
|
||||||
|
int l_addedNetmask = 0;
|
||||||
|
|
||||||
|
size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
||||||
|
struct rtattr *l_rta;
|
||||||
|
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
||||||
|
{
|
||||||
|
void *l_rtaData = RTA_DATA(l_rta);
|
||||||
|
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
||||||
|
if(l_info->ifa_family == AF_PACKET)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(l_rta->rta_type)
|
||||||
|
{
|
||||||
|
case IFA_ADDRESS:
|
||||||
|
case IFA_LOCAL:
|
||||||
|
if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
|
||||||
|
{ // make room for netmask
|
||||||
|
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
||||||
|
l_addedNetmask = 1;
|
||||||
|
}
|
||||||
|
case IFA_BROADCAST:
|
||||||
|
l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
|
||||||
|
break;
|
||||||
|
case IFA_LABEL:
|
||||||
|
l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ifaddrs *l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
|
||||||
|
memset(l_entry, 0, sizeof(struct ifaddrs));
|
||||||
|
l_entry->ifa_name = p_links[l_info->ifa_index - 1]->ifa_name;
|
||||||
|
|
||||||
|
char *l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
|
||||||
|
char *l_addr = l_name + l_nameSize;
|
||||||
|
|
||||||
|
l_entry->ifa_flags = l_info->ifa_flags | p_links[l_info->ifa_index - 1]->ifa_flags;
|
||||||
|
|
||||||
|
l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
|
||||||
|
for(l_rta = (struct rtattr *)(((char *)l_info) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
|
||||||
|
{
|
||||||
|
void *l_rtaData = RTA_DATA(l_rta);
|
||||||
|
size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
|
||||||
|
switch(l_rta->rta_type)
|
||||||
|
{
|
||||||
|
case IFA_ADDRESS:
|
||||||
|
case IFA_BROADCAST:
|
||||||
|
case IFA_LOCAL:
|
||||||
|
{
|
||||||
|
size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
|
||||||
|
makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
|
||||||
|
if(l_info->ifa_family == AF_INET6)
|
||||||
|
{
|
||||||
|
if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
|
||||||
|
{
|
||||||
|
((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_rta->rta_type == IFA_ADDRESS)
|
||||||
|
{ // apparently in a point-to-point network IFA_ADDRESS contains the dest address and IFA_LOCAL contains the local address
|
||||||
|
if(l_entry->ifa_addr)
|
||||||
|
{
|
||||||
|
l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(l_rta->rta_type == IFA_LOCAL)
|
||||||
|
{
|
||||||
|
if(l_entry->ifa_addr)
|
||||||
|
{
|
||||||
|
l_entry->ifa_dstaddr = l_entry->ifa_addr;
|
||||||
|
}
|
||||||
|
l_entry->ifa_addr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
l_addr += NLMSG_ALIGN(l_addrLen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IFA_LABEL:
|
||||||
|
strncpy(l_name, l_rtaData, l_rtaDataSize);
|
||||||
|
l_name[l_rtaDataSize] = '\0';
|
||||||
|
l_entry->ifa_name = l_name;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
|
||||||
|
{
|
||||||
|
unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
|
||||||
|
unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
|
||||||
|
char l_mask[16] = {0};
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<(l_prefix/8); ++i)
|
||||||
|
{
|
||||||
|
l_mask[i] = 0xff;
|
||||||
|
}
|
||||||
|
l_mask[i] = 0xff << (8 - (l_prefix % 8));
|
||||||
|
|
||||||
|
makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
|
||||||
|
l_entry->ifa_netmask = (struct sockaddr *)l_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
addToEnd(p_resultList, l_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void interpret(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_links, struct ifaddrs **p_resultList)
|
||||||
|
{
|
||||||
|
pid_t l_pid = getpid();
|
||||||
|
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
||||||
|
{
|
||||||
|
unsigned int l_nlsize = p_netlinkList->m_size;
|
||||||
|
struct nlmsghdr *l_hdr;
|
||||||
|
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
||||||
|
{
|
||||||
|
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == RTM_NEWLINK)
|
||||||
|
{
|
||||||
|
interpretLink(l_hdr, p_links, p_resultList);
|
||||||
|
}
|
||||||
|
else if(l_hdr->nlmsg_type == RTM_NEWADDR)
|
||||||
|
{
|
||||||
|
interpretAddr(l_hdr, p_links, p_resultList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
|
||||||
|
{
|
||||||
|
unsigned l_links = 0;
|
||||||
|
pid_t l_pid = getpid();
|
||||||
|
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
|
||||||
|
{
|
||||||
|
unsigned int l_nlsize = p_netlinkList->m_size;
|
||||||
|
struct nlmsghdr *l_hdr;
|
||||||
|
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
|
||||||
|
{
|
||||||
|
if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == NLMSG_DONE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(l_hdr->nlmsg_type == RTM_NEWLINK)
|
||||||
|
{
|
||||||
|
++l_links;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return l_links;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getifaddrs(struct ifaddrs **ifap)
|
||||||
|
{
|
||||||
|
if(!ifap)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*ifap = NULL;
|
||||||
|
|
||||||
|
int l_socket = netlink_socket();
|
||||||
|
if(l_socket < 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlinkList *l_linkResults = getResultList(l_socket, RTM_GETLINK);
|
||||||
|
if(!l_linkResults)
|
||||||
|
{
|
||||||
|
close(l_socket);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetlinkList *l_addrResults = getResultList(l_socket, RTM_GETADDR);
|
||||||
|
if(!l_addrResults)
|
||||||
|
{
|
||||||
|
close(l_socket);
|
||||||
|
freeResultList(l_linkResults);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
|
||||||
|
struct ifaddrs *l_links[l_numLinks];
|
||||||
|
memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
|
||||||
|
|
||||||
|
interpret(l_socket, l_linkResults, l_links, ifap);
|
||||||
|
interpret(l_socket, l_addrResults, l_links, ifap);
|
||||||
|
|
||||||
|
freeResultList(l_linkResults);
|
||||||
|
freeResultList(l_addrResults);
|
||||||
|
close(l_socket);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeifaddrs(struct ifaddrs *ifa)
|
||||||
|
{
|
||||||
|
struct ifaddrs *l_cur;
|
||||||
|
while(ifa)
|
||||||
|
{
|
||||||
|
l_cur = ifa;
|
||||||
|
ifa = ifa->ifa_next;
|
||||||
|
free(l_cur);
|
||||||
|
}
|
||||||
|
}
|
54
externals/android-ifaddrs/ifaddrs.h
vendored
Normal file
54
externals/android-ifaddrs/ifaddrs.h
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1995, 1999
|
||||||
|
* Berkeley Software Design, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IFADDRS_H_
|
||||||
|
#define _IFADDRS_H_
|
||||||
|
|
||||||
|
struct ifaddrs {
|
||||||
|
struct ifaddrs *ifa_next;
|
||||||
|
char *ifa_name;
|
||||||
|
unsigned int ifa_flags;
|
||||||
|
struct sockaddr *ifa_addr;
|
||||||
|
struct sockaddr *ifa_netmask;
|
||||||
|
struct sockaddr *ifa_dstaddr;
|
||||||
|
void *ifa_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This may have been defined in <net/if.h>. Note that if <net/if.h> is
|
||||||
|
* to be included it must be included before this header file.
|
||||||
|
*/
|
||||||
|
#ifndef ifa_broadaddr
|
||||||
|
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
extern int getifaddrs(struct ifaddrs **ifap);
|
||||||
|
extern void freeifaddrs(struct ifaddrs *ifa);
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif
|
2
externals/boost
vendored
2
externals/boost
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 3c27c785ad0f8a742af02e620dc225673f3a12d8
|
Subproject commit 32f5cd8ebb35b29ccb3860861bd285f80804bc85
|
100
externals/cmake-modules/CitraHandleSystemLibs.cmake
vendored
100
externals/cmake-modules/CitraHandleSystemLibs.cmake
vendored
|
@ -1,100 +0,0 @@
|
||||||
option(USE_SYSTEM_LIBS "Use system libraries over bundled ones" OFF)
|
|
||||||
|
|
||||||
# System library options
|
|
||||||
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_QT "Use the system Qt lib (instead of the bundled one)" OFF "ENABLE_QT;MSVC OR APPLE" ON)
|
|
||||||
CMAKE_DEPENDENT_OPTION(USE_SYSTEM_MOLTENVK "Use the system MoltenVK lib (instead of the bundled one)" OFF "APPLE" OFF)
|
|
||||||
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
|
|
||||||
option(USE_SYSTEM_OPENSSL "Use the system OpenSSL libs (instead of the bundled LibreSSL)" OFF)
|
|
||||||
option(USE_SYSTEM_LIBUSB "Use the system libusb (instead of the bundled libusb)" OFF)
|
|
||||||
option(USE_SYSTEM_CPP_JWT "Use the system cpp-jwt (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_SOUNDTOUCH "Use the system SoundTouch (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_CPP_HTTPLIB "Use the system cpp-httplib (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_JSON "Use the system JSON (nlohmann-json3) package (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_DYNARMIC "Use the system dynarmic (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_FMT "Use the system fmt (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_XBYAK "Use the system xbyak (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_INIH "Use the system inih (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_FFMPEG_HEADERS "Use the system FFmpeg headers (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_GLSLANG "Use the system glslang and SPIR-V libraries (instead of the bundled ones)" OFF)
|
|
||||||
option(USE_SYSTEM_ZSTD "Use the system Zstandard library (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_ENET "Use the system libenet (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_CRYPTOPP "Use the system cryptopp (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_CUBEB "Use the system cubeb (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_LODEPNG "Use the system lodepng (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_OPENAL "Use the system OpenAL (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_VMA "Use the system VulkanMemoryAllocator (instead of the bundled one)" OFF)
|
|
||||||
option(USE_SYSTEM_VULKAN_HEADERS "Use the system Vulkan headers (instead of the bundled ones)" OFF)
|
|
||||||
option(USE_SYSTEM_CATCH2 "Use the system Catch2 (instead of the bundled one)" OFF)
|
|
||||||
|
|
||||||
# Qt and MoltenVK are handled separately
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_SDL2 "Disable system SDL2" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_BOOST "Disable system Boost" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_OPENSSL "Disable system OpenSSL" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_LIBUSB "Disable system LibUSB" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_CPP_JWT "Disable system cpp-jwt" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_SOUNDTOUCH "Disable system SoundTouch" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_CPP_HTTPLIB "Disable system cpp-httplib" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_JSON "Disable system JSON" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_DYNARMIC "Disable system Dynarmic" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_FMT "Disable system fmt" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_XBYAK "Disable system xbyak" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_INIH "Disable system inih" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_FFMPEG_HEADERS "Disable system ffmpeg" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_GLSLANG "Disable system glslang" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_ZSTD "Disable system Zstandard" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_ENET "Disable system libenet" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_CRYPTOPP "Disable system cryptopp" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_CUBEB "Disable system cubeb" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_LODEPNG "Disable system lodepng" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_OPENAL "Disable system OpenAL" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_VMA "Disable system VulkanMemoryAllocator" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_VULKAN_HEADERS "Disable system Vulkan headers" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
CMAKE_DEPENDENT_OPTION(DISABLE_SYSTEM_CATCH2 "Disable system Catch2" OFF "USE_SYSTEM_LIBS" OFF)
|
|
||||||
|
|
||||||
set(LIB_VAR_LIST
|
|
||||||
SDL2
|
|
||||||
BOOST
|
|
||||||
OPENSSL
|
|
||||||
LIBUSB
|
|
||||||
CPP_JWT
|
|
||||||
SOUNDTOUCH
|
|
||||||
CPP_HTTPLIB
|
|
||||||
JSON
|
|
||||||
DYNARMIC
|
|
||||||
FMT
|
|
||||||
XBYAK
|
|
||||||
INIH
|
|
||||||
FFMPEG_HEADERS
|
|
||||||
GLSLANG
|
|
||||||
ZSTD
|
|
||||||
ENET
|
|
||||||
CRYPTOPP
|
|
||||||
CUBEB
|
|
||||||
LODEPNG
|
|
||||||
OPENAL
|
|
||||||
VMA
|
|
||||||
VULKAN_HEADERS
|
|
||||||
CATCH2
|
|
||||||
)
|
|
||||||
|
|
||||||
# First, check that USE_SYSTEM_XXX is not used with USE_SYSTEM_LIBS
|
|
||||||
|
|
||||||
if(USE_SYSTEM_LIBS)
|
|
||||||
foreach(CURRENT_LIB IN LISTS LIB_VAR_LIST)
|
|
||||||
if(USE_SYSTEM_${CURRENT_LIB})
|
|
||||||
unset(USE_SYSTEM_${CURRENT_LIB})
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
# Next, set which libraries to use
|
|
||||||
|
|
||||||
foreach(CURRENT_LIB IN LISTS LIB_VAR_LIST)
|
|
||||||
if(NOT DISABLE_SYSTEM_${CURRENT_LIB})
|
|
||||||
set(USE_SYSTEM_${CURRENT_LIB} ON CACHE BOOL "Using system ${CURRENT_LIB}" FORCE)
|
|
||||||
else()
|
|
||||||
# Explicitly disable this in case of multiple CMake invocations
|
|
||||||
set(USE_SYSTEM_${CURRENT_LIB} OFF CACHE BOOL "Using system ${CURRENT_LIB}" FORCE)
|
|
||||||
endif()
|
|
||||||
endforeach()
|
|
||||||
endif()
|
|
46
externals/cmake-modules/FindCppHttp.cmake
vendored
46
externals/cmake-modules/FindCppHttp.cmake
vendored
|
@ -1,46 +0,0 @@
|
||||||
if(NOT CppHttp_FOUND)
|
|
||||||
pkg_check_modules(CPP_HTTPLIB cpp-httplib)
|
|
||||||
|
|
||||||
if (CPP_HTTPLIB_FOUND)
|
|
||||||
find_path(HTTPLIB_INCLUDE_DIR NAMES httplib.h
|
|
||||||
PATHS
|
|
||||||
${CPP_HTTPLIB_INCLUDE_DIRS}
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(HTTPLIB_LIBRARY NAMES cpp-httplib
|
|
||||||
PATHS
|
|
||||||
${CPP_HTTPLIB_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
set(HTTPLIB_VERSION ${CPP_HTTPLIB_VERSION})
|
|
||||||
|
|
||||||
if (NOT TARGET cpp-httplib::cpp-httplib)
|
|
||||||
add_library(cpp-httplib::cpp-httplib INTERFACE IMPORTED)
|
|
||||||
set_target_properties(cpp-httplib::cpp-httplib PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${HTTPLIB_INCLUDE_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "${HTTPLIB_LIBRARY}"
|
|
||||||
IMPORTED_LOCATION "${HTTPLIB_LIBRARY}"
|
|
||||||
)
|
|
||||||
add_library(httplib::httplib ALIAS cpp-httplib::cpp-httplib)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
message(STATUS "Cpp-httplib not found via pkg-config, trying CMake...")
|
|
||||||
find_package(httplib)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
find_package_handle_standard_args(CppHttp REQUIRED_VARS HTTPLIB_INCLUDE_DIR HTTPLIB_LIBRARY VERSION_VAR HTTPLIB_VERSION)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CppHttp_FOUND AND NOT TARGET cpp-httplib::cpp-httplib)
|
|
||||||
add_library(cpp-httplib::cpp-httplib INTERFACE IMPORTED)
|
|
||||||
set_target_properties(cpp-httplib::cpp-httplib PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${CPP-HTTP_INCLUDE_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "${CPP-HTTP_LIBRARIES}"
|
|
||||||
IMPORTED_LOCATION "${CPP-HTTP_LIBRARIES}"
|
|
||||||
)
|
|
||||||
endif()
|
|
36
externals/cmake-modules/FindOpenAL.cmake
vendored
36
externals/cmake-modules/FindOpenAL.cmake
vendored
|
@ -1,36 +0,0 @@
|
||||||
if(NOT OPENAL_FOUND)
|
|
||||||
pkg_check_modules(OPENAL_TMP openal)
|
|
||||||
|
|
||||||
find_path(OPENAL_INCLUDE_DIRS NAMES al.h
|
|
||||||
PATHS
|
|
||||||
${OPENAL_TMP_INCLUDE_DIRS}
|
|
||||||
/usr/include/AL
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include/AL
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(OPENAL_LIBRARY_DIRS NAMES openal
|
|
||||||
PATHS
|
|
||||||
${OPENAL_TMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(OPENAL_INCLUDE_DIRS AND OPENAL_LIBRARY_DIRS)
|
|
||||||
set(OPENAL_FOUND TRUE CACHE INTERNAL "OpenAL found")
|
|
||||||
message(STATUS "Found OpenAL: ${OPENAL_LIBRARY_DIRS}, ${OPENAL_INCLUDE_DIRS}")
|
|
||||||
else()
|
|
||||||
set(OPENAL_FOUND FALSE CACHE INTERNAL "OpenAL found")
|
|
||||||
message(STATUS "OpenAL not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OPENAL_FOUND AND NOT TARGET OpenAL::OpenAL)
|
|
||||||
add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
|
|
||||||
set_target_properties(OpenAL::OpenAL PROPERTIES
|
|
||||||
INCLUDE_DIRECTORIES ${OPENAL_INCLUDE_DIRS}
|
|
||||||
INTERFACE_LINK_LIBRARIES ${OPENAL_LIBRARY_DIRS}
|
|
||||||
IMPORTED_LOCATION ${OPENAL_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
endif()
|
|
27
externals/cmake-modules/FindSoundTouch.cmake
vendored
27
externals/cmake-modules/FindSoundTouch.cmake
vendored
|
@ -1,27 +0,0 @@
|
||||||
if(NOT SOUNDTOUCH_FOUND)
|
|
||||||
pkg_check_modules(SOUNDTOUCH_TMP soundtouch)
|
|
||||||
|
|
||||||
find_path(SOUNDTOUCH_INCLUDE_DIRS NAMES SoundTouch.h
|
|
||||||
PATHS
|
|
||||||
${SOUNDTOUCH_TMP_INCLUDE_DIRS}
|
|
||||||
/usr/include/soundtouch
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include/soundtouch
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(SOUNDTOUCH_LIBRARIES NAMES SoundTouch
|
|
||||||
PATHS
|
|
||||||
${SOUNDTOUCH_TMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(SOUNDTOUCH_INCLUDE_DIRS AND SOUNDTOUCH_LIBRARIES)
|
|
||||||
set(SOUNDTOUCH_FOUND TRUE CACHE INTERNAL "SoundTouch found")
|
|
||||||
message(STATUS "Found SoundTouch: ${SOUNDTOUCH_INCLUDE_DIRS}, ${SOUNDTOUCH_LIBRARIES}")
|
|
||||||
else()
|
|
||||||
set(SOUNDTOUCH_FOUND FALSE CACHE INTERNAL "SoundTouch found")
|
|
||||||
message(STATUS "SoundTouch not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
35
externals/cmake-modules/Findcryptopp.cmake
vendored
35
externals/cmake-modules/Findcryptopp.cmake
vendored
|
@ -1,35 +0,0 @@
|
||||||
if(NOT CRYPTOPP_FOUND)
|
|
||||||
pkg_search_module(CRYPTOPP_TMP crypto++ cryptopp)
|
|
||||||
|
|
||||||
find_path(CRYPTOPP_INCLUDE_DIRS NAMES cryptlib.h
|
|
||||||
PATHS
|
|
||||||
${CRYPTOPP_TMP_INCLUDE_DIRS}
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include
|
|
||||||
PATH_SUFFIXES crypto++ cryptopp
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(CRYPTOPP_LIBRARY_DIRS NAMES crypto++ cryptopp
|
|
||||||
PATHS
|
|
||||||
${CRYPTOPP_TMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(CRYPTOPP_INCLUDE_DIRS AND CRYPTOPP_LIBRARY_DIRS)
|
|
||||||
set(CRYPTOPP_FOUND TRUE CACHE INTERNAL "Found cryptopp")
|
|
||||||
message(STATUS "Found cryptopp: ${CRYPTOPP_LIBRARY_DIRS}, ${CRYPTOPP_INCLUDE_DIRS}")
|
|
||||||
else()
|
|
||||||
set(CRYPTOPP_FOUND FALSE CACHE INTERNAL "Found cryptopp")
|
|
||||||
message(STATUS "Cryptopp not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CRYPTOPP_FOUND AND NOT TARGET cryptopp::cryptopp)
|
|
||||||
add_library(cryptopp::cryptopp UNKNOWN IMPORTED)
|
|
||||||
set_target_properties(cryptopp::cryptopp PROPERTIES
|
|
||||||
INCLUDE_DIRECTORIES ${CRYPTOPP_INCLUDE_DIRS}
|
|
||||||
INTERFACE_LINK_LIBRARIES ${CRYPTOPP_LIBRARY_DIRS}
|
|
||||||
IMPORTED_LOCATION ${CRYPTOPP_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
endif()
|
|
63
externals/cmake-modules/Findinih.cmake
vendored
63
externals/cmake-modules/Findinih.cmake
vendored
|
@ -1,63 +0,0 @@
|
||||||
if(NOT inih_FOUND)
|
|
||||||
# Inih includes both a base library and INIReader
|
|
||||||
# We must link against both to avoid linker errors.
|
|
||||||
|
|
||||||
pkg_check_modules(INIR_TEMP INIReader)
|
|
||||||
pkg_check_modules(INIH_TEMP inih)
|
|
||||||
|
|
||||||
|
|
||||||
find_path(INIR_INCLUDE_DIR NAMES INIReader.h
|
|
||||||
PATHS
|
|
||||||
${INIR_TEMP_INCLUDE_DIRS}
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_path(INIH_INCLUDE_DIR NAMES ini.h
|
|
||||||
PATHS
|
|
||||||
${INIH_TEMP_INCLUDE_DIRS}
|
|
||||||
/usr/include
|
|
||||||
/use/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(INIR_LIBRARIES NAMES INIReader
|
|
||||||
PATHS
|
|
||||||
${INIR_TEMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(INIH_LIBRARIES NAMES inih
|
|
||||||
PATHS
|
|
||||||
${INIH_TEMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(INIR_INCLUDE_DIR AND INIH_INCLUDE_DIR AND INIR_LIBRARIES AND INIH_LIBRARIES)
|
|
||||||
set(inih_FOUND TRUE CACHE INTERNAL "Found inih library")
|
|
||||||
message(STATUS "Found inih ${INIR_INCLUDE_DIR} ${INIH_INCLUDE_DIR} ${INIR_LIBRARIES} ${INIH_LIBRARIES}")
|
|
||||||
else()
|
|
||||||
set(inih_FOUND FALSE CACHE INTERNAL "Found inih library")
|
|
||||||
message(STATUS "Inih not found.")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(inih_FOUND AND NOT TARGET inih::inir OR NOT TARGET inih::inih)
|
|
||||||
add_library(inih::inir INTERFACE IMPORTED)
|
|
||||||
set_target_properties(inih::inir PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${INIR_INCLUDE_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "${INIR_LIBRARIES}"
|
|
||||||
IMPORTED_LOCATION "${INIR_LIBRARIES}"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_library(inih::inih INTERFACE IMPORTED)
|
|
||||||
set_target_properties(inih::inih PROPERTIES
|
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${INIH_INCLUDE_DIR}"
|
|
||||||
INTERFACE_LINK_LIBRARIES "${INIH_LIBRARES}"
|
|
||||||
IMPORTED_LOCATION ${INIH_LIBRARIES}
|
|
||||||
)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
34
externals/cmake-modules/Findlibenet.cmake
vendored
34
externals/cmake-modules/Findlibenet.cmake
vendored
|
@ -1,34 +0,0 @@
|
||||||
if(NOT libenet_FOUND)
|
|
||||||
pkg_check_modules(ENET_TMP libenet)
|
|
||||||
|
|
||||||
find_path(libenet_INCLUDE_DIRS NAMES enet.h PATH_SUFFIXES enet
|
|
||||||
PATHS
|
|
||||||
${ENET_TMP_INCLUDE_DIRS}
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(libenet_LIBRARY_DIRS NAMES enet
|
|
||||||
PATHS
|
|
||||||
${ENET_TMP_LIBRARY_DIRS}
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(libenet_INCLUDE_DIRS AND libenet_LIBRARY_DIRS)
|
|
||||||
set(libenet_FOUND TRUE CACHE INTERNAL "Found libenet")
|
|
||||||
message(STATUS "Found libenet ${libenet_LIBRARY_DIRS}, ${libenet_INCLUDE_DIRS}")
|
|
||||||
else()
|
|
||||||
set(libenet_FOUND FALSE CACHE INTERNAL "Found libenet")
|
|
||||||
message(STATUS "Libenet not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(libenet_FOUND AND NOT TARGET libenet::libenet)
|
|
||||||
add_library(libenet::libenet UNKNOWN IMPORTED)
|
|
||||||
set_target_properties(libenet::libenet PROPERTIES
|
|
||||||
INCLUDE_DIRECTORIES ${libenet_INCLUDE_DIRS}
|
|
||||||
INTERFACE_LINK_LIBRARIES ${libenet_LIBRARY_DIRS}
|
|
||||||
IMPORTED_LOCATION ${libenet_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
endif()
|
|
31
externals/cmake-modules/Findlodepng.cmake
vendored
31
externals/cmake-modules/Findlodepng.cmake
vendored
|
@ -1,31 +0,0 @@
|
||||||
if(NOT LODEPNG_FOUND)
|
|
||||||
find_path(LODEPNG_INCLUDE_DIRS NAMES lodepng.h
|
|
||||||
PATHS
|
|
||||||
/usr/include
|
|
||||||
/usr/local/include
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LODEPNG_LIBRARY_DIRS NAMES lodepng
|
|
||||||
PATHS
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
if(LODEPNG_INCLUDE_DIRS AND LODEPNG_LIBRARY_DIRS)
|
|
||||||
set(LODEPNG_FOUND TRUE CACHE INTERNAL "Found lodepng")
|
|
||||||
message(STATUS "Found lodepng: ${LODEPNG_LIBRARY_DIRS}, ${LODEPNG_INCLUDE_DIRS}")
|
|
||||||
else()
|
|
||||||
set(LODEPNG_FOUND FALSE CACHE INTERNAL "Found lodepng")
|
|
||||||
message(STATUS "Lodepng not found.")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LODEPNG_FOUND AND NOT TARGET lodepng::lodepng)
|
|
||||||
add_library(lodepng::lodepng UNKNOWN IMPORTED)
|
|
||||||
set_target_properties(lodepng::lodepng PROPERTIES
|
|
||||||
INCLUDE_DIRECTORIES ${LODEPNG_INCLUDE_DIRS}
|
|
||||||
INTERFACE_LINK_LIBRARIES ${LODEPNG_LIBRARY_DIRS}
|
|
||||||
IMPORTED_LOCATION ${LODEPNG_LIBRARY_DIRS}
|
|
||||||
)
|
|
||||||
|
|
||||||
endif()
|
|
2
externals/cryptopp
vendored
2
externals/cryptopp
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit af7d1050bf2287072edd629be133da458a3cf978
|
Subproject commit 511806c0eba8ba5b5cedd4b4a814e96df92864a6
|
2
externals/cryptopp-cmake
vendored
2
externals/cryptopp-cmake
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit a99c80c26686e44eddf0432140ae397f3efbd0b3
|
Subproject commit 15798ac9c2611d5c7f9ba832e2c9159bdd8945f2
|
2
externals/cubeb
vendored
2
externals/cubeb
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 799e775484b8fce7e986ee7a4f4b651fec2bca07
|
Subproject commit 48689ae7a73caeb747953f9ed664dc71d2f918d8
|
2
externals/discord-rpc
vendored
2
externals/discord-rpc
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 20cc99aeffa08a4834f156b6ab49ed68618cf94a
|
Subproject commit 963aa9f3e5ce81a4682c6ca3d136cddda614db33
|
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 30f1a3c6289075ef4af08f5ec502be2fc8627a0c
|
Subproject commit d333a09b3b9152af3cb442902ae8ea18d8416470
|
88
externals/faad2/CMakeLists.txt
vendored
88
externals/faad2/CMakeLists.txt
vendored
|
@ -1,88 +0,0 @@
|
||||||
# Sources cut down to just what we need for AAC-LC.
|
|
||||||
set(FAAD2_SOURCE_DIR "faad2/libfaad")
|
|
||||||
add_library(faad2 STATIC EXCLUDE_FROM_ALL
|
|
||||||
"${FAAD2_SOURCE_DIR}/bits.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/cfft.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/common.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/decoder.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/drc.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/error.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/filtbank.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/huffman.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/is.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/mdct.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/mp4.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/ms.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/output.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/pns.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/pulse.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/specrec.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/syntax.c"
|
|
||||||
"${FAAD2_SOURCE_DIR}/tns.c"
|
|
||||||
)
|
|
||||||
target_include_directories(faad2 PUBLIC faad2/include PRIVATE "${FAAD2_SOURCE_DIR}")
|
|
||||||
|
|
||||||
# Configure compile definitions.
|
|
||||||
|
|
||||||
# Read version from properties file for configuring constant.
|
|
||||||
file(READ faad2/properties.json FAAD_PROPERTIES_JSON)
|
|
||||||
string(JSON FAAD_VERSION GET ${FAAD_PROPERTIES_JSON} PACKAGE_VERSION)
|
|
||||||
message(STATUS "Building faad2 version ${FAAD_VERSION}")
|
|
||||||
|
|
||||||
# Check for functions and headers.
|
|
||||||
include(CheckFunctionExists)
|
|
||||||
include(CheckIncludeFiles)
|
|
||||||
check_function_exists(getpwuid HAVE_GETPWUID)
|
|
||||||
check_function_exists(lrintf HAVE_LRINTF)
|
|
||||||
check_function_exists(memcpy HAVE_MEMCPY)
|
|
||||||
check_function_exists(strchr HAVE_STRCHR)
|
|
||||||
check_function_exists(strsep HAVE_STRSEP)
|
|
||||||
check_include_files(dlfcn.h HAVE_DLFCN_H)
|
|
||||||
check_include_files(errno.h HAVE_ERRNO_H)
|
|
||||||
check_include_files(float.h HAVE_FLOAT_H)
|
|
||||||
check_include_files(inttypes.h HAVE_INTTYPES_H)
|
|
||||||
check_include_files(IOKit/IOKitLib.h HAVE_IOKIT_IOKITLIB_H)
|
|
||||||
check_include_files(limits.h HAVE_LIMITS_H)
|
|
||||||
check_include_files(mathf.h HAVE_MATHF_H)
|
|
||||||
check_include_files(stdint.h HAVE_STDINT_H)
|
|
||||||
check_include_files(stdio.h HAVE_STDIO_H)
|
|
||||||
check_include_files(stdlib.h HAVE_STDLIB_H)
|
|
||||||
check_include_files(strings.h HAVE_STRINGS_H)
|
|
||||||
check_include_files(string.h HAVE_STRING_H)
|
|
||||||
check_include_files(sysfs/libsysfs.h HAVE_SYSFS_LIBSYSFS_H)
|
|
||||||
check_include_files(sys/stat.h HAVE_SYS_STAT_H)
|
|
||||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
|
||||||
check_include_files(sys/types.h HAVE_SYS_TYPES_H)
|
|
||||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
|
||||||
|
|
||||||
# faad2 uses a relative include for its config.h which breaks under CMake.
|
|
||||||
# We can use target_compile_definitions to pass on the configuration instead.
|
|
||||||
target_compile_definitions(faad2 PRIVATE
|
|
||||||
-DFAAD_VERSION=${FAAD_VERSION}
|
|
||||||
-DPACKAGE_VERSION=\"${FAAD_VERSION}\"
|
|
||||||
-DSTDC_HEADERS
|
|
||||||
-DHAVE_GETPWUID=${HAVE_GETPWUID}
|
|
||||||
-DHAVE_LRINTF=${HAVE_LRINTF}
|
|
||||||
-DHAVE_MEMCPY=${HAVE_MEMCPY}
|
|
||||||
-DHAVE_STRCHR=${HAVE_STRCHR}
|
|
||||||
-DHAVE_STRSEP=${HAVE_STRSEP}
|
|
||||||
-DHAVE_DLFCN_H=${HAVE_DLFCN_H}
|
|
||||||
-DHAVE_ERRNO_H=${HAVE_ERRNO_H}
|
|
||||||
-DHAVE_FLOAT_H=${HAVE_FLOAT_H}
|
|
||||||
-DHAVE_INTTYPES_H=${HAVE_INTTYPES_H}
|
|
||||||
-DHAVE_IOKIT_IOKITLIB_H=${HAVE_IOKIT_IOKITLIB_H}
|
|
||||||
-DHAVE_LIMITS_H=${HAVE_LIMITS_H}
|
|
||||||
-DHAVE_MATHF_H=${HAVE_MATHF_H}
|
|
||||||
-DHAVE_STDINT_H=${HAVE_STDINT_H}
|
|
||||||
-DHAVE_STDIO_H=${HAVE_STDIO_H}
|
|
||||||
-DHAVE_STDLIB_H=${HAVE_STDLIB_H}
|
|
||||||
-DHAVE_STRINGS_H=${HAVE_STRINGS_H}
|
|
||||||
-DHAVE_STRING_H=${HAVE_STRING_H}
|
|
||||||
-DHAVE_SYSFS_LIBSYSFS_H=${HAVE_SYSFS_LIBSYSFS_H}
|
|
||||||
-DHAVE_SYS_STAT_H=${HAVE_SYS_STAT_H}
|
|
||||||
-DHAVE_SYS_TIME_H=${HAVE_SYS_TIME_H}
|
|
||||||
-DHAVE_SYS_TYPES_H=${HAVE_SYS_TYPES_H}
|
|
||||||
-DHAVE_UNISTD_H=${HAVE_UNISTD_H}
|
|
||||||
# Only compile for AAC-LC decoding.
|
|
||||||
-DLC_ONLY_DECODER -DDISABLE_SBR
|
|
||||||
)
|
|
1
externals/faad2/faad2
vendored
1
externals/faad2/faad2
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 09b3c850c606e7fedd06597223e54344e8d23c8c
|
|
2
externals/fmt
vendored
2
externals/fmt
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 2dd4fa8742fdac36468f8d8ea3e06e78215551f8
|
Subproject commit a33701196adfad74917046096bf5a2aa0ab0bb50
|
9
externals/gamemode/CMakeLists.txt
vendored
9
externals/gamemode/CMakeLists.txt
vendored
|
@ -1,9 +0,0 @@
|
||||||
# SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
project(gamemode LANGUAGES CXX C)
|
|
||||||
|
|
||||||
add_library(gamemode include/gamemode_client.h)
|
|
||||||
|
|
||||||
target_include_directories(gamemode PUBLIC include)
|
|
||||||
set_target_properties(gamemode PROPERTIES LINKER_LANGUAGE C)
|
|
379
externals/gamemode/include/gamemode_client.h
vendored
379
externals/gamemode/include/gamemode_client.h
vendored
|
@ -1,379 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2017-2019 Feral Interactive
|
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2017-2019, Feral Interactive
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright notice,
|
|
||||||
this list of conditions and the following disclaimer.
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
* Neither the name of Feral Interactive nor the names of its contributors
|
|
||||||
may be used to endorse or promote products derived from this software
|
|
||||||
without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
||||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
*/
|
|
||||||
#ifndef CLIENT_GAMEMODE_H
|
|
||||||
#define CLIENT_GAMEMODE_H
|
|
||||||
/*
|
|
||||||
* GameMode supports the following client functions
|
|
||||||
* Requests are refcounted in the daemon
|
|
||||||
*
|
|
||||||
* int gamemode_request_start() - Request gamemode starts
|
|
||||||
* 0 if the request was sent successfully
|
|
||||||
* -1 if the request failed
|
|
||||||
*
|
|
||||||
* int gamemode_request_end() - Request gamemode ends
|
|
||||||
* 0 if the request was sent successfully
|
|
||||||
* -1 if the request failed
|
|
||||||
*
|
|
||||||
* GAMEMODE_AUTO can be defined to make the above two functions apply during static init and
|
|
||||||
* destruction, as appropriate. In this configuration, errors will be printed to stderr
|
|
||||||
*
|
|
||||||
* int gamemode_query_status() - Query the current status of gamemode
|
|
||||||
* 0 if gamemode is inactive
|
|
||||||
* 1 if gamemode is active
|
|
||||||
* 2 if gamemode is active and this client is registered
|
|
||||||
* -1 if the query failed
|
|
||||||
*
|
|
||||||
* int gamemode_request_start_for(pid_t pid) - Request gamemode starts for another process
|
|
||||||
* 0 if the request was sent successfully
|
|
||||||
* -1 if the request failed
|
|
||||||
* -2 if the request was rejected
|
|
||||||
*
|
|
||||||
* int gamemode_request_end_for(pid_t pid) - Request gamemode ends for another process
|
|
||||||
* 0 if the request was sent successfully
|
|
||||||
* -1 if the request failed
|
|
||||||
* -2 if the request was rejected
|
|
||||||
*
|
|
||||||
* int gamemode_query_status_for(pid_t pid) - Query status of gamemode for another process
|
|
||||||
* 0 if gamemode is inactive
|
|
||||||
* 1 if gamemode is active
|
|
||||||
* 2 if gamemode is active and this client is registered
|
|
||||||
* -1 if the query failed
|
|
||||||
*
|
|
||||||
* const char* gamemode_error_string() - Get an error string
|
|
||||||
* returns a string describing any of the above errors
|
|
||||||
*
|
|
||||||
* Note: All the above requests can be blocking - dbus requests can and will block while the daemon
|
|
||||||
* handles the request. It is not recommended to make these calls in performance critical code
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
static char internal_gamemode_client_error_string[512] = { 0 };
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Load libgamemode dynamically to dislodge us from most dependencies.
|
|
||||||
* This allows clients to link and/or use this regardless of runtime.
|
|
||||||
* See SDL2 for an example of the reasoning behind this in terms of
|
|
||||||
* dynamic versioning as well.
|
|
||||||
*/
|
|
||||||
static volatile int internal_libgamemode_loaded = 1;
|
|
||||||
|
|
||||||
/* Typedefs for the functions to load */
|
|
||||||
typedef int (*api_call_return_int)(void);
|
|
||||||
typedef const char *(*api_call_return_cstring)(void);
|
|
||||||
typedef int (*api_call_pid_return_int)(pid_t);
|
|
||||||
|
|
||||||
/* Storage for functors */
|
|
||||||
static api_call_return_int REAL_internal_gamemode_request_start = NULL;
|
|
||||||
static api_call_return_int REAL_internal_gamemode_request_end = NULL;
|
|
||||||
static api_call_return_int REAL_internal_gamemode_query_status = NULL;
|
|
||||||
static api_call_return_cstring REAL_internal_gamemode_error_string = NULL;
|
|
||||||
static api_call_pid_return_int REAL_internal_gamemode_request_start_for = NULL;
|
|
||||||
static api_call_pid_return_int REAL_internal_gamemode_request_end_for = NULL;
|
|
||||||
static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal helper to perform the symbol binding safely.
|
|
||||||
*
|
|
||||||
* Returns 0 on success and -1 on failure
|
|
||||||
*/
|
|
||||||
__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol(
|
|
||||||
void *handle, const char *name, void **out_func, size_t func_size, bool required)
|
|
||||||
{
|
|
||||||
void *symbol_lookup = NULL;
|
|
||||||
char *dl_error = NULL;
|
|
||||||
|
|
||||||
/* Safely look up the symbol */
|
|
||||||
symbol_lookup = dlsym(handle, name);
|
|
||||||
dl_error = dlerror();
|
|
||||||
if (required && (dl_error || !symbol_lookup)) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"dlsym failed - %s",
|
|
||||||
dl_error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Have the symbol correctly, copy it to make it usable */
|
|
||||||
memcpy(out_func, &symbol_lookup, func_size);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads libgamemode and needed functions
|
|
||||||
*
|
|
||||||
* Returns 0 on success and -1 on failure
|
|
||||||
*/
|
|
||||||
__attribute__((always_inline)) static inline int internal_load_libgamemode(void)
|
|
||||||
{
|
|
||||||
/* We start at 1, 0 is a success and -1 is a fail */
|
|
||||||
if (internal_libgamemode_loaded != 1) {
|
|
||||||
return internal_libgamemode_loaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Anonymous struct type to define our bindings */
|
|
||||||
struct binding {
|
|
||||||
const char *name;
|
|
||||||
void **functor;
|
|
||||||
size_t func_size;
|
|
||||||
bool required;
|
|
||||||
} bindings[] = {
|
|
||||||
{ "real_gamemode_request_start",
|
|
||||||
(void **)&REAL_internal_gamemode_request_start,
|
|
||||||
sizeof(REAL_internal_gamemode_request_start),
|
|
||||||
true },
|
|
||||||
{ "real_gamemode_request_end",
|
|
||||||
(void **)&REAL_internal_gamemode_request_end,
|
|
||||||
sizeof(REAL_internal_gamemode_request_end),
|
|
||||||
true },
|
|
||||||
{ "real_gamemode_query_status",
|
|
||||||
(void **)&REAL_internal_gamemode_query_status,
|
|
||||||
sizeof(REAL_internal_gamemode_query_status),
|
|
||||||
false },
|
|
||||||
{ "real_gamemode_error_string",
|
|
||||||
(void **)&REAL_internal_gamemode_error_string,
|
|
||||||
sizeof(REAL_internal_gamemode_error_string),
|
|
||||||
true },
|
|
||||||
{ "real_gamemode_request_start_for",
|
|
||||||
(void **)&REAL_internal_gamemode_request_start_for,
|
|
||||||
sizeof(REAL_internal_gamemode_request_start_for),
|
|
||||||
false },
|
|
||||||
{ "real_gamemode_request_end_for",
|
|
||||||
(void **)&REAL_internal_gamemode_request_end_for,
|
|
||||||
sizeof(REAL_internal_gamemode_request_end_for),
|
|
||||||
false },
|
|
||||||
{ "real_gamemode_query_status_for",
|
|
||||||
(void **)&REAL_internal_gamemode_query_status_for,
|
|
||||||
sizeof(REAL_internal_gamemode_query_status_for),
|
|
||||||
false },
|
|
||||||
};
|
|
||||||
|
|
||||||
void *libgamemode = NULL;
|
|
||||||
|
|
||||||
/* Try and load libgamemode */
|
|
||||||
libgamemode = dlopen("libgamemode.so.0", RTLD_NOW);
|
|
||||||
if (!libgamemode) {
|
|
||||||
/* Attempt to load unversioned library for compatibility with older
|
|
||||||
* versions (as of writing, there are no ABI changes between the two -
|
|
||||||
* this may need to change if ever ABI-breaking changes are made) */
|
|
||||||
libgamemode = dlopen("libgamemode.so", RTLD_NOW);
|
|
||||||
if (!libgamemode) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"dlopen failed - %s",
|
|
||||||
dlerror());
|
|
||||||
internal_libgamemode_loaded = -1;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Attempt to bind all symbols */
|
|
||||||
for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) {
|
|
||||||
struct binding *binder = &bindings[i];
|
|
||||||
|
|
||||||
if (internal_bind_libgamemode_symbol(libgamemode,
|
|
||||||
binder->name,
|
|
||||||
binder->functor,
|
|
||||||
binder->func_size,
|
|
||||||
binder->required)) {
|
|
||||||
internal_libgamemode_loaded = -1;
|
|
||||||
return -1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Success */
|
|
||||||
internal_libgamemode_loaded = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to the real libgamemode
|
|
||||||
*/
|
|
||||||
__attribute__((always_inline)) static inline const char *gamemode_error_string(void)
|
|
||||||
{
|
|
||||||
/* If we fail to load the system gamemode, or we have an error string already, return our error
|
|
||||||
* string instead of diverting to the system version */
|
|
||||||
if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') {
|
|
||||||
return internal_gamemode_client_error_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assert for static analyser that the function is not NULL */
|
|
||||||
assert(REAL_internal_gamemode_error_string != NULL);
|
|
||||||
|
|
||||||
return REAL_internal_gamemode_error_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redirect to the real libgamemode
|
|
||||||
* Allow automatically requesting game mode
|
|
||||||
* Also prints errors as they happen.
|
|
||||||
*/
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
__attribute__((constructor))
|
|
||||||
#else
|
|
||||||
__attribute__((always_inline)) static inline
|
|
||||||
#endif
|
|
||||||
int gamemode_request_start(void)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assert for static analyser that the function is not NULL */
|
|
||||||
assert(REAL_internal_gamemode_request_start != NULL);
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_request_start() < 0) {
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Redirect to the real libgamemode */
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
__attribute__((destructor))
|
|
||||||
#else
|
|
||||||
__attribute__((always_inline)) static inline
|
|
||||||
#endif
|
|
||||||
int gamemode_request_end(void)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Assert for static analyser that the function is not NULL */
|
|
||||||
assert(REAL_internal_gamemode_request_end != NULL);
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_request_end() < 0) {
|
|
||||||
#ifdef GAMEMODE_AUTO
|
|
||||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string());
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Redirect to the real libgamemode */
|
|
||||||
__attribute__((always_inline)) static inline int gamemode_query_status(void)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_query_status == NULL) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"gamemode_query_status missing (older host?)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return REAL_internal_gamemode_query_status();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Redirect to the real libgamemode */
|
|
||||||
__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_request_start_for == NULL) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"gamemode_request_start_for missing (older host?)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return REAL_internal_gamemode_request_start_for(pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Redirect to the real libgamemode */
|
|
||||||
__attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_request_end_for == NULL) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"gamemode_request_end_for missing (older host?)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return REAL_internal_gamemode_request_end_for(pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Redirect to the real libgamemode */
|
|
||||||
__attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid)
|
|
||||||
{
|
|
||||||
/* Need to load gamemode */
|
|
||||||
if (internal_load_libgamemode() < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (REAL_internal_gamemode_query_status_for == NULL) {
|
|
||||||
snprintf(internal_gamemode_client_error_string,
|
|
||||||
sizeof(internal_gamemode_client_error_string),
|
|
||||||
"gamemode_query_status_for missing (older host?)");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return REAL_internal_gamemode_query_status_for(pid);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // CLIENT_GAMEMODE_H
|
|
6
externals/glad/Readme.md
vendored
6
externals/glad/Readme.md
vendored
|
@ -3,9 +3,3 @@ These files were generated by the [glad](https://github.com/Dav1dde/glad) OpenGL
|
||||||
```
|
```
|
||||||
python -m glad --profile core --out-path glad/ --api "gl=4.3,gles2=3.2" --generator=c
|
python -m glad --profile core --out-path glad/ --api "gl=4.3,gles2=3.2" --generator=c
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also generate the source using [this site](https://glad.dav1d.de/):
|
|
||||||
1. Select '4.3' for GL, '3.2' for GLES2, and 'Core' for Profile.
|
|
||||||
2. Input the currently supported extensions from [here](https://github.com/citra-emu/citra/blob/master/externals/glad/include/glad/glad.h#L9), plus any new required extensions.
|
|
||||||
3. Click Generate and download the generated source zip.
|
|
||||||
4. Unzip the new source over the current glad source files.
|
|
60
externals/glad/include/glad/glad.h
vendored
60
externals/glad/include/glad/glad.h
vendored
|
@ -1,35 +1,28 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Fri Nov 10 04:24:01 2023.
|
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Sat Apr 1 20:34:42 2023.
|
||||||
|
|
||||||
Language/Generator: C/C++
|
Language/Generator: C/C++
|
||||||
Specification: gl
|
Specification: gl
|
||||||
APIs: gl=4.3, gles2=3.2
|
APIs: gl=4.3, gles2=3.2
|
||||||
Profile: core
|
Profile: core
|
||||||
Extensions:
|
Extensions:
|
||||||
GL_AMD_blend_minmax_factor,
|
|
||||||
GL_ARB_buffer_storage,
|
GL_ARB_buffer_storage,
|
||||||
GL_ARB_clear_texture,
|
GL_ARB_clear_texture,
|
||||||
GL_ARB_fragment_shader_interlock,
|
|
||||||
GL_ARB_get_texture_sub_image,
|
GL_ARB_get_texture_sub_image,
|
||||||
GL_ARB_texture_compression_bptc,
|
GL_ARB_texture_compression_bptc,
|
||||||
GL_ARM_shader_framebuffer_fetch,
|
|
||||||
GL_EXT_buffer_storage,
|
GL_EXT_buffer_storage,
|
||||||
GL_EXT_clip_cull_distance,
|
GL_EXT_clip_cull_distance,
|
||||||
GL_EXT_shader_framebuffer_fetch,
|
GL_EXT_texture_compression_s3tc
|
||||||
GL_EXT_texture_compression_s3tc,
|
|
||||||
GL_INTEL_fragment_shader_ordering,
|
|
||||||
GL_NV_blend_minmax_factor,
|
|
||||||
GL_NV_fragment_shader_interlock
|
|
||||||
Loader: True
|
Loader: True
|
||||||
Local files: False
|
Local files: False
|
||||||
Omit khrplatform: False
|
Omit khrplatform: False
|
||||||
Reproducible: False
|
Reproducible: False
|
||||||
|
|
||||||
Commandline:
|
Commandline:
|
||||||
--profile="core" --api="gl=4.3,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_AMD_blend_minmax_factor,GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_fragment_shader_interlock,GL_ARB_get_texture_sub_image,GL_ARB_texture_compression_bptc,GL_ARM_shader_framebuffer_fetch,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance,GL_EXT_shader_framebuffer_fetch,GL_EXT_texture_compression_s3tc,GL_INTEL_fragment_shader_ordering,GL_NV_blend_minmax_factor,GL_NV_fragment_shader_interlock"
|
--profile="core" --api="gl=4.3,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_get_texture_sub_image,GL_ARB_texture_compression_bptc,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance,GL_EXT_texture_compression_s3tc"
|
||||||
Online:
|
Online:
|
||||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.3&api=gles2%3D3.2&extensions=GL_AMD_blend_minmax_factor&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_fragment_shader_interlock&extensions=GL_ARB_get_texture_sub_image&extensions=GL_ARB_texture_compression_bptc&extensions=GL_ARM_shader_framebuffer_fetch&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_shader_framebuffer_fetch&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_INTEL_fragment_shader_ordering&extensions=GL_NV_blend_minmax_factor&extensions=GL_NV_fragment_shader_interlock
|
https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.3&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_get_texture_sub_image&extensions=GL_ARB_texture_compression_bptc&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_texture_compression_s3tc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -3327,8 +3320,6 @@ typedef void (APIENTRYP PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location,
|
||||||
GLAPI PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
|
GLAPI PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
|
||||||
#define glGetnUniformuiv glad_glGetnUniformuiv
|
#define glGetnUniformuiv glad_glGetnUniformuiv
|
||||||
#endif
|
#endif
|
||||||
#define GL_FACTOR_MIN_AMD 0x901C
|
|
||||||
#define GL_FACTOR_MAX_AMD 0x901D
|
|
||||||
#define GL_MAP_PERSISTENT_BIT 0x0040
|
#define GL_MAP_PERSISTENT_BIT 0x0040
|
||||||
#define GL_MAP_COHERENT_BIT 0x0080
|
#define GL_MAP_COHERENT_BIT 0x0080
|
||||||
#define GL_DYNAMIC_STORAGE_BIT 0x0100
|
#define GL_DYNAMIC_STORAGE_BIT 0x0100
|
||||||
|
@ -3341,13 +3332,10 @@ GLAPI PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
|
||||||
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
|
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D
|
||||||
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
|
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E
|
||||||
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
|
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F
|
||||||
#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52
|
|
||||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||||
#define GL_FETCH_PER_SAMPLE_ARM 0x8F65
|
|
||||||
#define GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM 0x8F66
|
|
||||||
#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
|
#define GL_MAP_PERSISTENT_BIT_EXT 0x0040
|
||||||
#define GL_MAP_COHERENT_BIT_EXT 0x0080
|
#define GL_MAP_COHERENT_BIT_EXT 0x0080
|
||||||
#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
|
#define GL_DYNAMIC_STORAGE_BIT_EXT 0x0100
|
||||||
|
@ -3366,10 +3354,6 @@ GLAPI PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv;
|
||||||
#define GL_CLIP_DISTANCE5_EXT 0x3005
|
#define GL_CLIP_DISTANCE5_EXT 0x3005
|
||||||
#define GL_CLIP_DISTANCE6_EXT 0x3006
|
#define GL_CLIP_DISTANCE6_EXT 0x3006
|
||||||
#define GL_CLIP_DISTANCE7_EXT 0x3007
|
#define GL_CLIP_DISTANCE7_EXT 0x3007
|
||||||
#ifndef GL_AMD_blend_minmax_factor
|
|
||||||
#define GL_AMD_blend_minmax_factor 1
|
|
||||||
GLAPI int GLAD_GL_AMD_blend_minmax_factor;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_ARB_buffer_storage
|
#ifndef GL_ARB_buffer_storage
|
||||||
#define GL_ARB_buffer_storage 1
|
#define GL_ARB_buffer_storage 1
|
||||||
GLAPI int GLAD_GL_ARB_buffer_storage;
|
GLAPI int GLAD_GL_ARB_buffer_storage;
|
||||||
|
@ -3387,10 +3371,6 @@ typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level,
|
||||||
GLAPI PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage;
|
GLAPI PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage;
|
||||||
#define glClearTexSubImage glad_glClearTexSubImage
|
#define glClearTexSubImage glad_glClearTexSubImage
|
||||||
#endif
|
#endif
|
||||||
#ifndef GL_ARB_fragment_shader_interlock
|
|
||||||
#define GL_ARB_fragment_shader_interlock 1
|
|
||||||
GLAPI int GLAD_GL_ARB_fragment_shader_interlock;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_ARB_get_texture_sub_image
|
#ifndef GL_ARB_get_texture_sub_image
|
||||||
#define GL_ARB_get_texture_sub_image 1
|
#define GL_ARB_get_texture_sub_image 1
|
||||||
GLAPI int GLAD_GL_ARB_get_texture_sub_image;
|
GLAPI int GLAD_GL_ARB_get_texture_sub_image;
|
||||||
|
@ -3405,30 +3385,10 @@ GLAPI PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage;
|
||||||
#define GL_ARB_texture_compression_bptc 1
|
#define GL_ARB_texture_compression_bptc 1
|
||||||
GLAPI int GLAD_GL_ARB_texture_compression_bptc;
|
GLAPI int GLAD_GL_ARB_texture_compression_bptc;
|
||||||
#endif
|
#endif
|
||||||
#ifndef GL_EXT_shader_framebuffer_fetch
|
|
||||||
#define GL_EXT_shader_framebuffer_fetch 1
|
|
||||||
GLAPI int GLAD_GL_EXT_shader_framebuffer_fetch;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_EXT_texture_compression_s3tc
|
#ifndef GL_EXT_texture_compression_s3tc
|
||||||
#define GL_EXT_texture_compression_s3tc 1
|
#define GL_EXT_texture_compression_s3tc 1
|
||||||
GLAPI int GLAD_GL_EXT_texture_compression_s3tc;
|
GLAPI int GLAD_GL_EXT_texture_compression_s3tc;
|
||||||
#endif
|
#endif
|
||||||
#ifndef GL_INTEL_fragment_shader_ordering
|
|
||||||
#define GL_INTEL_fragment_shader_ordering 1
|
|
||||||
GLAPI int GLAD_GL_INTEL_fragment_shader_ordering;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_NV_blend_minmax_factor
|
|
||||||
#define GL_NV_blend_minmax_factor 1
|
|
||||||
GLAPI int GLAD_GL_NV_blend_minmax_factor;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_NV_fragment_shader_interlock
|
|
||||||
#define GL_NV_fragment_shader_interlock 1
|
|
||||||
GLAPI int GLAD_GL_NV_fragment_shader_interlock;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_ARM_shader_framebuffer_fetch
|
|
||||||
#define GL_ARM_shader_framebuffer_fetch 1
|
|
||||||
GLAPI int GLAD_GL_ARM_shader_framebuffer_fetch;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_EXT_buffer_storage
|
#ifndef GL_EXT_buffer_storage
|
||||||
#define GL_EXT_buffer_storage 1
|
#define GL_EXT_buffer_storage 1
|
||||||
GLAPI int GLAD_GL_EXT_buffer_storage;
|
GLAPI int GLAD_GL_EXT_buffer_storage;
|
||||||
|
@ -3440,22 +3400,10 @@ GLAPI PFNGLBUFFERSTORAGEEXTPROC glad_glBufferStorageEXT;
|
||||||
#define GL_EXT_clip_cull_distance 1
|
#define GL_EXT_clip_cull_distance 1
|
||||||
GLAPI int GLAD_GL_EXT_clip_cull_distance;
|
GLAPI int GLAD_GL_EXT_clip_cull_distance;
|
||||||
#endif
|
#endif
|
||||||
#ifndef GL_EXT_shader_framebuffer_fetch
|
|
||||||
#define GL_EXT_shader_framebuffer_fetch 1
|
|
||||||
GLAPI int GLAD_GL_EXT_shader_framebuffer_fetch;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_EXT_texture_compression_s3tc
|
#ifndef GL_EXT_texture_compression_s3tc
|
||||||
#define GL_EXT_texture_compression_s3tc 1
|
#define GL_EXT_texture_compression_s3tc 1
|
||||||
GLAPI int GLAD_GL_EXT_texture_compression_s3tc;
|
GLAPI int GLAD_GL_EXT_texture_compression_s3tc;
|
||||||
#endif
|
#endif
|
||||||
#ifndef GL_NV_blend_minmax_factor
|
|
||||||
#define GL_NV_blend_minmax_factor 1
|
|
||||||
GLAPI int GLAD_GL_NV_blend_minmax_factor;
|
|
||||||
#endif
|
|
||||||
#ifndef GL_NV_fragment_shader_interlock
|
|
||||||
#define GL_NV_fragment_shader_interlock 1
|
|
||||||
GLAPI int GLAD_GL_NV_fragment_shader_interlock;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
32
externals/glad/src/glad.c
vendored
32
externals/glad/src/glad.c
vendored
|
@ -1,35 +1,28 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Fri Nov 10 04:24:01 2023.
|
OpenGL, OpenGL ES loader generated by glad 0.1.36 on Sat Apr 1 20:34:42 2023.
|
||||||
|
|
||||||
Language/Generator: C/C++
|
Language/Generator: C/C++
|
||||||
Specification: gl
|
Specification: gl
|
||||||
APIs: gl=4.3, gles2=3.2
|
APIs: gl=4.3, gles2=3.2
|
||||||
Profile: core
|
Profile: core
|
||||||
Extensions:
|
Extensions:
|
||||||
GL_AMD_blend_minmax_factor,
|
|
||||||
GL_ARB_buffer_storage,
|
GL_ARB_buffer_storage,
|
||||||
GL_ARB_clear_texture,
|
GL_ARB_clear_texture,
|
||||||
GL_ARB_fragment_shader_interlock,
|
|
||||||
GL_ARB_get_texture_sub_image,
|
GL_ARB_get_texture_sub_image,
|
||||||
GL_ARB_texture_compression_bptc,
|
GL_ARB_texture_compression_bptc,
|
||||||
GL_ARM_shader_framebuffer_fetch,
|
|
||||||
GL_EXT_buffer_storage,
|
GL_EXT_buffer_storage,
|
||||||
GL_EXT_clip_cull_distance,
|
GL_EXT_clip_cull_distance,
|
||||||
GL_EXT_shader_framebuffer_fetch,
|
GL_EXT_texture_compression_s3tc
|
||||||
GL_EXT_texture_compression_s3tc,
|
|
||||||
GL_INTEL_fragment_shader_ordering,
|
|
||||||
GL_NV_blend_minmax_factor,
|
|
||||||
GL_NV_fragment_shader_interlock
|
|
||||||
Loader: True
|
Loader: True
|
||||||
Local files: False
|
Local files: False
|
||||||
Omit khrplatform: False
|
Omit khrplatform: False
|
||||||
Reproducible: False
|
Reproducible: False
|
||||||
|
|
||||||
Commandline:
|
Commandline:
|
||||||
--profile="core" --api="gl=4.3,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_AMD_blend_minmax_factor,GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_fragment_shader_interlock,GL_ARB_get_texture_sub_image,GL_ARB_texture_compression_bptc,GL_ARM_shader_framebuffer_fetch,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance,GL_EXT_shader_framebuffer_fetch,GL_EXT_texture_compression_s3tc,GL_INTEL_fragment_shader_ordering,GL_NV_blend_minmax_factor,GL_NV_fragment_shader_interlock"
|
--profile="core" --api="gl=4.3,gles2=3.2" --generator="c" --spec="gl" --extensions="GL_ARB_buffer_storage,GL_ARB_clear_texture,GL_ARB_get_texture_sub_image,GL_ARB_texture_compression_bptc,GL_EXT_buffer_storage,GL_EXT_clip_cull_distance,GL_EXT_texture_compression_s3tc"
|
||||||
Online:
|
Online:
|
||||||
https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.3&api=gles2%3D3.2&extensions=GL_AMD_blend_minmax_factor&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_fragment_shader_interlock&extensions=GL_ARB_get_texture_sub_image&extensions=GL_ARB_texture_compression_bptc&extensions=GL_ARM_shader_framebuffer_fetch&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_shader_framebuffer_fetch&extensions=GL_EXT_texture_compression_s3tc&extensions=GL_INTEL_fragment_shader_ordering&extensions=GL_NV_blend_minmax_factor&extensions=GL_NV_fragment_shader_interlock
|
https://glad.dav1d.de/#profile=core&language=c&specification=gl&loader=on&api=gl%3D4.3&api=gles2%3D3.2&extensions=GL_ARB_buffer_storage&extensions=GL_ARB_clear_texture&extensions=GL_ARB_get_texture_sub_image&extensions=GL_ARB_texture_compression_bptc&extensions=GL_EXT_buffer_storage&extensions=GL_EXT_clip_cull_distance&extensions=GL_EXT_texture_compression_s3tc
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -860,20 +853,13 @@ PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv = NULL;
|
||||||
PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
|
PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf = NULL;
|
||||||
PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
|
PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv = NULL;
|
||||||
PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
|
PFNGLWAITSYNCPROC glad_glWaitSync = NULL;
|
||||||
int GLAD_GL_AMD_blend_minmax_factor = 0;
|
|
||||||
int GLAD_GL_ARB_buffer_storage = 0;
|
int GLAD_GL_ARB_buffer_storage = 0;
|
||||||
int GLAD_GL_ARB_clear_texture = 0;
|
int GLAD_GL_ARB_clear_texture = 0;
|
||||||
int GLAD_GL_ARB_fragment_shader_interlock = 0;
|
|
||||||
int GLAD_GL_ARB_get_texture_sub_image = 0;
|
int GLAD_GL_ARB_get_texture_sub_image = 0;
|
||||||
int GLAD_GL_ARB_texture_compression_bptc = 0;
|
int GLAD_GL_ARB_texture_compression_bptc = 0;
|
||||||
int GLAD_GL_ARM_shader_framebuffer_fetch = 0;
|
|
||||||
int GLAD_GL_EXT_buffer_storage = 0;
|
int GLAD_GL_EXT_buffer_storage = 0;
|
||||||
int GLAD_GL_EXT_clip_cull_distance = 0;
|
int GLAD_GL_EXT_clip_cull_distance = 0;
|
||||||
int GLAD_GL_EXT_shader_framebuffer_fetch = 0;
|
|
||||||
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
||||||
int GLAD_GL_INTEL_fragment_shader_ordering = 0;
|
|
||||||
int GLAD_GL_NV_blend_minmax_factor = 0;
|
|
||||||
int GLAD_GL_NV_fragment_shader_interlock = 0;
|
|
||||||
PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
|
PFNGLBUFFERSTORAGEPROC glad_glBufferStorage = NULL;
|
||||||
PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
|
PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage = NULL;
|
||||||
PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
|
PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage = NULL;
|
||||||
|
@ -1512,17 +1498,11 @@ static void load_GL_ARB_get_texture_sub_image(GLADloadproc load) {
|
||||||
}
|
}
|
||||||
static int find_extensionsGL(void) {
|
static int find_extensionsGL(void) {
|
||||||
if (!get_exts()) return 0;
|
if (!get_exts()) return 0;
|
||||||
GLAD_GL_AMD_blend_minmax_factor = has_ext("GL_AMD_blend_minmax_factor");
|
|
||||||
GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage");
|
GLAD_GL_ARB_buffer_storage = has_ext("GL_ARB_buffer_storage");
|
||||||
GLAD_GL_ARB_clear_texture = has_ext("GL_ARB_clear_texture");
|
GLAD_GL_ARB_clear_texture = has_ext("GL_ARB_clear_texture");
|
||||||
GLAD_GL_ARB_fragment_shader_interlock = has_ext("GL_ARB_fragment_shader_interlock");
|
|
||||||
GLAD_GL_ARB_get_texture_sub_image = has_ext("GL_ARB_get_texture_sub_image");
|
GLAD_GL_ARB_get_texture_sub_image = has_ext("GL_ARB_get_texture_sub_image");
|
||||||
GLAD_GL_ARB_texture_compression_bptc = has_ext("GL_ARB_texture_compression_bptc");
|
GLAD_GL_ARB_texture_compression_bptc = has_ext("GL_ARB_texture_compression_bptc");
|
||||||
GLAD_GL_EXT_shader_framebuffer_fetch = has_ext("GL_EXT_shader_framebuffer_fetch");
|
|
||||||
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
|
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
|
||||||
GLAD_GL_INTEL_fragment_shader_ordering = has_ext("GL_INTEL_fragment_shader_ordering");
|
|
||||||
GLAD_GL_NV_blend_minmax_factor = has_ext("GL_NV_blend_minmax_factor");
|
|
||||||
GLAD_GL_NV_fragment_shader_interlock = has_ext("GL_NV_fragment_shader_interlock");
|
|
||||||
free_exts();
|
free_exts();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1991,13 +1971,9 @@ static void load_GL_EXT_buffer_storage(GLADloadproc load) {
|
||||||
}
|
}
|
||||||
static int find_extensionsGLES2(void) {
|
static int find_extensionsGLES2(void) {
|
||||||
if (!get_exts()) return 0;
|
if (!get_exts()) return 0;
|
||||||
GLAD_GL_ARM_shader_framebuffer_fetch = has_ext("GL_ARM_shader_framebuffer_fetch");
|
|
||||||
GLAD_GL_EXT_buffer_storage = has_ext("GL_EXT_buffer_storage");
|
GLAD_GL_EXT_buffer_storage = has_ext("GL_EXT_buffer_storage");
|
||||||
GLAD_GL_EXT_clip_cull_distance = has_ext("GL_EXT_clip_cull_distance");
|
GLAD_GL_EXT_clip_cull_distance = has_ext("GL_EXT_clip_cull_distance");
|
||||||
GLAD_GL_EXT_shader_framebuffer_fetch = has_ext("GL_EXT_shader_framebuffer_fetch");
|
|
||||||
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
|
GLAD_GL_EXT_texture_compression_s3tc = has_ext("GL_EXT_texture_compression_s3tc");
|
||||||
GLAD_GL_NV_blend_minmax_factor = has_ext("GL_NV_blend_minmax_factor");
|
|
||||||
GLAD_GL_NV_fragment_shader_interlock = has_ext("GL_NV_fragment_shader_interlock");
|
|
||||||
free_exts();
|
free_exts();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
2
externals/httplib/README.md
vendored
2
externals/httplib/README.md
vendored
|
@ -1,4 +1,4 @@
|
||||||
From https://github.com/yhirose/cpp-httplib/commit/0a629d739127dcc5d828474a5aedae1f234687d3
|
From https://github.com/yhirose/cpp-httplib/commit/8e10d4e8e7febafce0632810262e81e853b2065f
|
||||||
|
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
|
|
1848
externals/httplib/httplib.h
vendored
1848
externals/httplib/httplib.h
vendored
File diff suppressed because it is too large
Load diff
2
externals/inih/CMakeLists.txt
vendored
2
externals/inih/CMakeLists.txt
vendored
|
@ -6,4 +6,4 @@ add_library(inih
|
||||||
)
|
)
|
||||||
|
|
||||||
create_target_directory_groups(inih)
|
create_target_directory_groups(inih)
|
||||||
target_include_directories(inih INTERFACE ./inih/cpp)
|
target_include_directories(inih INTERFACE .)
|
||||||
|
|
1
externals/libadrenotools
vendored
1
externals/libadrenotools
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit deec5f75ee1a8ccbe32c8780b1d17284fc87b0f1
|
|
1
externals/library-headers
vendored
1
externals/library-headers
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 3b3e28dbe6d033395ce2967fa8030825e7b89de7
|
|
48
externals/library-headers/CMakeLists.txt
vendored
Normal file
48
externals/library-headers/CMakeLists.txt
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
add_library(library-headers INTERFACE)
|
||||||
|
|
||||||
|
# libfdk-aac headers
|
||||||
|
find_path(FDK_AAC_INCLUDES NAMES fdk-aac/aacdecoder_lib.h)
|
||||||
|
if (FDK_AAC_INCLUDES STREQUAL "FDK_AAC_INCLUDES-NOTFOUND")
|
||||||
|
message(STATUS "fdk_aac headers not found, using bundled headers.")
|
||||||
|
target_include_directories(library-headers INTERFACE ./library-headers/fdk-aac/include)
|
||||||
|
else()
|
||||||
|
message(STATUS "Using headers from system fdk_aac")
|
||||||
|
target_include_directories(library-headers SYSTEM INTERFACE ${FDK_AAC_INCLUDES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# FFmpeg headers
|
||||||
|
find_path(AVUTIL_INCLUDES NAMES libavutil/avutil.h)
|
||||||
|
find_path(AVCODEC_INCLUDES NAMES libavcodec/avcodec.h)
|
||||||
|
find_path(AVFORMAT_INCLUDES NAMES libavformat/avformat.h)
|
||||||
|
find_path(AVFILTER_INCLUDES NAMES libavfilter/avfilter.h)
|
||||||
|
find_path(SWRESAMPLE_INCLUDES NAMES libswresample/swresample.h)
|
||||||
|
# Make sure all the headers are found and from the same place, so we don't
|
||||||
|
# have missing or mismatched components.
|
||||||
|
if (AVUTIL_INCLUDES STREQUAL "AVUTIL_INCLUDES-NOTFOUND"
|
||||||
|
OR NOT AVCODEC_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||||
|
OR NOT AVFORMAT_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||||
|
OR NOT AVFILTER_INCLUDES STREQUAL AVUTIL_INCLUDES
|
||||||
|
OR NOT SWRESAMPLE_INCLUDES STREQUAL AVUTIL_INCLUDES)
|
||||||
|
message(STATUS "Complete FFmpeg headers not found, using bundled headers.")
|
||||||
|
target_include_directories(library-headers INTERFACE ./library-headers/ffmpeg/include)
|
||||||
|
else()
|
||||||
|
# Extract libavutil version from header.
|
||||||
|
file(STRINGS "${AVUTIL_INCLUDES}/libavutil/version.h" AVUTIL_VERSION_DATA
|
||||||
|
REGEX "#define LIBAVUTIL_VERSION_(MAJOR|MINOR|MICRO) ")
|
||||||
|
set(AVUTIL_VERSION_REGEX "([0-9]+)")
|
||||||
|
foreach(v MAJOR MINOR MICRO)
|
||||||
|
if("${AVUTIL_VERSION_DATA}" MATCHES "#define LIBAVUTIL_VERSION_${v}[\\t ]+${AVUTIL_VERSION_REGEX}")
|
||||||
|
set(AVUTIL_VERSION_${v} "${CMAKE_MATCH_1}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(AVUTIL_VERSION "${AVUTIL_VERSION_MAJOR}.${AVUTIL_VERSION_MINOR}.${AVUTIL_VERSION_MICRO}")
|
||||||
|
|
||||||
|
message(STATUS "Detected FFmpeg libavutil version is ${AVUTIL_VERSION}")
|
||||||
|
if ("${AVUTIL_VERSION}" VERSION_LESS "56.30.100")
|
||||||
|
message(WARNING "System FFmpeg version is too low (< 4.2), using bundled headers.")
|
||||||
|
target_include_directories(library-headers INTERFACE ./library-headers/ffmpeg/include)
|
||||||
|
else()
|
||||||
|
message(STATUS "Using headers from system FFmpeg")
|
||||||
|
target_include_directories(library-headers SYSTEM INTERFACE ${AVUTIL_INCLUDES})
|
||||||
|
endif()
|
||||||
|
endif()
|
1
externals/library-headers/library-headers
vendored
Submodule
1
externals/library-headers/library-headers
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 071bc4282ca29ec255ab2dae32c978481ca5dfea
|
2
externals/libressl
vendored
2
externals/libressl
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit d4fc7348a3fbe9c659a373e28a3b50f052f7c50a
|
Subproject commit dcf9a84aba598f827f65d946d31c3c93af62790a
|
1
externals/oaknut
vendored
1
externals/oaknut
vendored
|
@ -1 +0,0 @@
|
||||||
Subproject commit 6b1d57ea7ed4882d32a91eeaa6557b0ecb4da152
|
|
2
externals/vulkan-headers
vendored
2
externals/vulkan-headers
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit 217e93c664ec6704ec2d8c36fa116c1a4a1e2d40
|
Subproject commit bae9700cd9425541a0f6029957f005e5ad3ef660
|
BIN
keys.tar.enc
Normal file
BIN
keys.tar.enc
Normal file
Binary file not shown.
|
@ -5,10 +5,6 @@ include_directories(.)
|
||||||
set_property(DIRECTORY APPEND PROPERTY
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
|
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
|
||||||
|
|
||||||
if (ENABLE_LTO)
|
|
||||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set compilation flags
|
# Set compilation flags
|
||||||
if (MSVC)
|
if (MSVC)
|
||||||
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
||||||
|
@ -44,6 +40,7 @@ if (MSVC)
|
||||||
/Zo
|
/Zo
|
||||||
/permissive-
|
/permissive-
|
||||||
/EHsc
|
/EHsc
|
||||||
|
/std:c++latest
|
||||||
/utf-8
|
/utf-8
|
||||||
/volatile:iso
|
/volatile:iso
|
||||||
/Zc:externConstexpr
|
/Zc:externConstexpr
|
||||||
|
@ -51,10 +48,6 @@ if (MSVC)
|
||||||
/Zc:throwingNew
|
/Zc:throwingNew
|
||||||
/GT
|
/GT
|
||||||
|
|
||||||
# Some flags for more deterministic builds, to aid caching.
|
|
||||||
/experimental:deterministic
|
|
||||||
/d1trimfile:"${CMAKE_SOURCE_DIR}"
|
|
||||||
|
|
||||||
# External headers diagnostics
|
# External headers diagnostics
|
||||||
/experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
|
/experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
|
||||||
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
|
/external:anglebrackets # Treats all headers included by #include <header>, where the header file is enclosed in angle brackets (< >), as external headers
|
||||||
|
@ -91,8 +84,7 @@ if (MSVC)
|
||||||
|
|
||||||
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
# Since MSVC's debugging information is not very deterministic, so we have to disable it
|
||||||
# when using ccache or other caching tools
|
# when using ccache or other caching tools
|
||||||
if (CMAKE_C_COMPILER_LAUNCHER STREQUAL "ccache" OR CMAKE_CXX_COMPILER_LAUNCHER STREQUAL "ccache"
|
if (CITRA_USE_CCACHE OR CITRA_USE_PRECOMPILED_HEADERS)
|
||||||
OR CITRA_USE_PRECOMPILED_HEADERS)
|
|
||||||
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
# Precompiled headers are deleted if not using /Z7. See https://github.com/nanoant/CMakePCHCompiler/issues/21
|
||||||
add_compile_options(/Z7)
|
add_compile_options(/Z7)
|
||||||
else()
|
else()
|
||||||
|
@ -103,23 +95,13 @@ if (MSVC)
|
||||||
add_compile_options("$<$<CONFIG:Release>:/GS->")
|
add_compile_options("$<$<CONFIG:Release>:/GS->")
|
||||||
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE)
|
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE)
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF /PDBALTPATH:%_PDB%" CACHE STRING "" FORCE)
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
|
||||||
else()
|
else()
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall
|
-Wall
|
||||||
# In case a flag isn't supported on e.g. a certain architecture, don't error.
|
-Wno-attributes
|
||||||
-Wno-unused-command-line-argument
|
|
||||||
# Build fortification options
|
|
||||||
-Wp,-D_GLIBCXX_ASSERTIONS
|
|
||||||
-fstack-protector-strong
|
|
||||||
-fstack-clash-protection
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
||||||
# _FORTIFY_SOURCE can't be used without optimizations.
|
|
||||||
add_compile_options(-Wp,-D_FORTIFY_SOURCE=2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (CITRA_WARNINGS_AS_ERRORS)
|
if (CITRA_WARNINGS_AS_ERRORS)
|
||||||
add_compile_options(-Werror)
|
add_compile_options(-Werror)
|
||||||
endif()
|
endif()
|
||||||
|
@ -128,13 +110,6 @@ else()
|
||||||
add_compile_options("-stdlib=libc++")
|
add_compile_options("-stdlib=libc++")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
|
|
||||||
# GCC may warn when it ignores attributes like maybe_unused,
|
|
||||||
# which is a problem for older versions (e.g. GCC 11).
|
|
||||||
add_compile_options("-Wno-attributes")
|
|
||||||
add_compile_options("-Wno-interference-size")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
add_definitions(-DMINGW_HAS_SECURE_API)
|
add_definitions(-DMINGW_HAS_SECURE_API)
|
||||||
if (COMPILE_WITH_DWARF)
|
if (COMPILE_WITH_DWARF)
|
||||||
|
@ -159,16 +134,6 @@ else()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(ENABLE_SOFTWARE_RENDERER)
|
|
||||||
add_compile_definitions(ENABLE_SOFTWARE_RENDERER)
|
|
||||||
endif()
|
|
||||||
if(ENABLE_OPENGL)
|
|
||||||
add_compile_definitions(ENABLE_OPENGL)
|
|
||||||
endif()
|
|
||||||
if(ENABLE_VULKAN)
|
|
||||||
add_compile_definitions(ENABLE_VULKAN)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(video_core)
|
add_subdirectory(video_core)
|
||||||
|
|
192
src/android/app/build.gradle
Normal file
192
src/android/app/build.gradle
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the number of seconds/10 since Jan 1 2016 as the versionCode.
|
||||||
|
* This lets us upload a new build at most every 10 seconds for the
|
||||||
|
* next 680 years.
|
||||||
|
*/
|
||||||
|
def autoVersion = (int) (((new Date().getTime() / 1000) - 1451606400) / 10)
|
||||||
|
def buildType
|
||||||
|
def abiFilter = "arm64-v8a" //, "x86"
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 33
|
||||||
|
ndkVersion "25.1.8937393"
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
// This is important as it will run lint but not abort on error
|
||||||
|
// Lint has some overly obnoxious "errors" that should really be warnings
|
||||||
|
abortOnError false
|
||||||
|
|
||||||
|
//Uncomment disable lines for test builds...
|
||||||
|
//disable 'MissingTranslation'bin
|
||||||
|
//disable 'ExtraTranslation'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// TODO If this is ever modified, change application_id in strings.xml
|
||||||
|
applicationId "org.citra.citra_emu"
|
||||||
|
minSdkVersion 28
|
||||||
|
targetSdkVersion 31
|
||||||
|
versionCode autoVersion
|
||||||
|
versionName getVersion()
|
||||||
|
ndk.abiFilters abiFilter
|
||||||
|
}
|
||||||
|
|
||||||
|
def keystoreFile = System.getenv('ANDROID_KEYSTORE_FILE')
|
||||||
|
if (keystoreFile != null) {
|
||||||
|
signingConfigs {
|
||||||
|
release {
|
||||||
|
storeFile file(keystoreFile)
|
||||||
|
storePassword System.getenv('ANDROID_KEYSTORE_PASS')
|
||||||
|
keyAlias System.getenv('ANDROID_KEY_ALIAS')
|
||||||
|
keyPassword System.getenv('ANDROID_KEYSTORE_PASS')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
applicationVariants.all { variant ->
|
||||||
|
buildType = variant.buildType.name // sets the current build type
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define build types, which are orthogonal to product flavors.
|
||||||
|
buildTypes {
|
||||||
|
|
||||||
|
// Signed by release key, allowing for upload to Play Store.
|
||||||
|
release {
|
||||||
|
signingConfig keystoreFile != null ? signingConfigs.release : signingConfigs.debug
|
||||||
|
}
|
||||||
|
|
||||||
|
// builds a release build that doesn't need signing
|
||||||
|
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||||
|
relWithDebInfo {
|
||||||
|
initWith release
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
versionNameSuffix '-debug'
|
||||||
|
signingConfig signingConfigs.debug
|
||||||
|
minifyEnabled false
|
||||||
|
testCoverageEnabled false
|
||||||
|
debuggable true
|
||||||
|
jniDebuggable true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signed by debug key disallowing distribution on Play Store.
|
||||||
|
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
||||||
|
debug {
|
||||||
|
// TODO If this is ever modified, change application_id in debug/strings.xml
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
versionNameSuffix '-debug'
|
||||||
|
debuggable true
|
||||||
|
jniDebuggable true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flavorDimensions "version"
|
||||||
|
productFlavors {
|
||||||
|
canary {
|
||||||
|
dimension "version"
|
||||||
|
applicationIdSuffix ".canary"
|
||||||
|
}
|
||||||
|
nightly {
|
||||||
|
dimension "version"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
version "3.22.1"
|
||||||
|
path "../../../CMakeLists.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
namespace 'org.citra.citra_emu'
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
externalNativeBuild {
|
||||||
|
cmake {
|
||||||
|
arguments "-DENABLE_QT=0", // Don't use QT
|
||||||
|
"-DENABLE_SDL2=0", // Don't use SDL
|
||||||
|
"-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work
|
||||||
|
|
||||||
|
abiFilters abiFilter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation "androidx.activity:activity:1.5.1"
|
||||||
|
implementation "androidx.fragment:fragment:1.5.5"
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||||
|
implementation 'androidx.exifinterface:exifinterface:1.3.4'
|
||||||
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
|
implementation "androidx.documentfile:documentfile:1.0.1"
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.5.1'
|
||||||
|
implementation 'androidx.fragment:fragment:1.5.3'
|
||||||
|
implementation "androidx.slidingpanelayout:slidingpanelayout:1.2.0"
|
||||||
|
implementation 'com.google.android.material:material:1.6.1'
|
||||||
|
implementation 'androidx.core:core-splashscreen:1.0.0'
|
||||||
|
implementation "androidx.work:work-runtime:2.8.1"
|
||||||
|
|
||||||
|
// For loading huge screenshots from the disk.
|
||||||
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
|
||||||
|
// Allows FRP-style asynchronous operations in Android.
|
||||||
|
implementation 'io.reactivex:rxandroid:1.2.1'
|
||||||
|
implementation 'org.ini4j:ini4j:0.5.4'
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
|
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'
|
||||||
|
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||||
|
|
||||||
|
// Please don't upgrade the billing library as the newer version is not GPL-compatible
|
||||||
|
implementation 'com.android.billingclient:billing:2.0.3'
|
||||||
|
|
||||||
|
// To use the androidx.test.core APIs
|
||||||
|
androidTestImplementation "androidx.test:core:1.5.0"
|
||||||
|
androidTestImplementation "androidx.test.ext:junit:1.1.5"
|
||||||
|
}
|
||||||
|
|
||||||
|
def getVersion() {
|
||||||
|
def versionName = '0.0'
|
||||||
|
|
||||||
|
try {
|
||||||
|
versionName = 'git describe --always --long'.execute([], project.rootDir).text
|
||||||
|
.trim()
|
||||||
|
.replaceAll(/(-0)?-[^-]+$/, "")
|
||||||
|
} catch (Exception) {
|
||||||
|
logger.error('Cannot find git, defaulting to dummy version number')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.getenv("GITHUB_ACTIONS") != null) {
|
||||||
|
def gitTag = System.getenv("GIT_TAG_NAME")
|
||||||
|
versionName = gitTag ?: versionName
|
||||||
|
}
|
||||||
|
|
||||||
|
return versionName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add task to each variant for copying output APKs to bundle directory.
|
||||||
|
android.applicationVariants.all { variant ->
|
||||||
|
def capitalizedName = variant.name.capitalize()
|
||||||
|
def copyTask = tasks.register("copyBundle${capitalizedName}") {
|
||||||
|
doLast {
|
||||||
|
project.copy {
|
||||||
|
from variant.outputs[0].outputFile.parentFile
|
||||||
|
include '*.apk'
|
||||||
|
into layout.buildDirectory.dir("bundle")
|
||||||
|
}
|
||||||
|
project.copy {
|
||||||
|
from layout.buildDirectory.dir("outputs/bundle/${variant.name}")
|
||||||
|
include '*.aab'
|
||||||
|
into layout.buildDirectory.dir("bundle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tasks.named("bundle${capitalizedName}").get().configure { finalizedBy copyTask }
|
||||||
|
}
|
|
@ -1,289 +0,0 @@
|
||||||
// Copyright 2023 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
import android.databinding.tool.ext.capitalizeUS
|
|
||||||
import de.undercouch.gradle.tasks.download.Download
|
|
||||||
|
|
||||||
plugins {
|
|
||||||
id("com.android.application")
|
|
||||||
id("org.jetbrains.kotlin.android")
|
|
||||||
id("de.undercouch.download") version "5.5.0"
|
|
||||||
id("kotlin-parcelize")
|
|
||||||
kotlin("plugin.serialization") version "1.9.22"
|
|
||||||
id("androidx.navigation.safeargs.kotlin")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the number of seconds/10 since Jan 1 2016 as the versionCode.
|
|
||||||
* This lets us upload a new build at most every 10 seconds for the
|
|
||||||
* next 680 years.
|
|
||||||
*/
|
|
||||||
val autoVersion = (((System.currentTimeMillis() / 1000) - 1451606400) / 10).toInt()
|
|
||||||
val abiFilter = listOf("arm64-v8a", "x86_64")
|
|
||||||
|
|
||||||
val downloadedJniLibsPath = "${buildDir}/downloadedJniLibs"
|
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
|
||||||
android {
|
|
||||||
namespace = "org.citra.citra_emu"
|
|
||||||
|
|
||||||
compileSdkVersion = "android-34"
|
|
||||||
ndkVersion = "26.1.10909125"
|
|
||||||
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_17
|
|
||||||
targetCompatibility = JavaVersion.VERSION_17
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "17"
|
|
||||||
}
|
|
||||||
|
|
||||||
androidResources {
|
|
||||||
generateLocaleConfig = true
|
|
||||||
}
|
|
||||||
|
|
||||||
packaging {
|
|
||||||
// This is necessary for libadrenotools custom driver loading
|
|
||||||
jniLibs.useLegacyPackaging = true
|
|
||||||
}
|
|
||||||
|
|
||||||
buildFeatures {
|
|
||||||
viewBinding = true
|
|
||||||
}
|
|
||||||
|
|
||||||
lint {
|
|
||||||
// This is important as it will run lint but not abort on error
|
|
||||||
// Lint has some overly obnoxious "errors" that should really be warnings
|
|
||||||
abortOnError = false
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
// TODO If this is ever modified, change application_id in strings.xml
|
|
||||||
applicationId = "org.citra.citra_emu"
|
|
||||||
minSdk = 28
|
|
||||||
targetSdk = 34
|
|
||||||
versionCode = autoVersion
|
|
||||||
versionName = getGitVersion()
|
|
||||||
|
|
||||||
ndk {
|
|
||||||
//noinspection ChromeOsAbiSupport
|
|
||||||
abiFilters += abiFilter
|
|
||||||
}
|
|
||||||
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
arguments(
|
|
||||||
"-DENABLE_QT=0", // Don't use QT
|
|
||||||
"-DENABLE_SDL2=0", // Don't use SDL
|
|
||||||
"-DANDROID_ARM_NEON=true" // cryptopp requires Neon to work
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buildConfigField("String", "GIT_HASH", "\"${getGitHash()}\"")
|
|
||||||
buildConfigField("String", "BRANCH", "\"${getBranch()}\"")
|
|
||||||
}
|
|
||||||
|
|
||||||
val keystoreFile = System.getenv("ANDROID_KEYSTORE_FILE")
|
|
||||||
if (keystoreFile != null) {
|
|
||||||
signingConfigs {
|
|
||||||
create("release") {
|
|
||||||
storeFile = file(keystoreFile)
|
|
||||||
storePassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
|
||||||
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
|
|
||||||
keyPassword = System.getenv("ANDROID_KEYSTORE_PASS")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Define build types, which are orthogonal to product flavors.
|
|
||||||
buildTypes {
|
|
||||||
// Signed by release key, allowing for upload to Play Store.
|
|
||||||
release {
|
|
||||||
signingConfig = if (keystoreFile != null) {
|
|
||||||
signingConfigs.getByName("release")
|
|
||||||
} else {
|
|
||||||
signingConfigs.getByName("debug")
|
|
||||||
}
|
|
||||||
isMinifyEnabled = true
|
|
||||||
isShrinkResources = true
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// builds a release build that doesn't need signing
|
|
||||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
|
||||||
register("relWithDebInfo") {
|
|
||||||
initWith(getByName("release"))
|
|
||||||
applicationIdSuffix = ".debug"
|
|
||||||
versionNameSuffix = "-debug"
|
|
||||||
signingConfig = signingConfigs.getByName("debug")
|
|
||||||
isMinifyEnabled = true
|
|
||||||
isShrinkResources = true
|
|
||||||
isDebuggable = true
|
|
||||||
isJniDebuggable = true
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
isDefault = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signed by debug key disallowing distribution on Play Store.
|
|
||||||
// Attaches 'debug' suffix to version and package name, allowing installation alongside the release build.
|
|
||||||
debug {
|
|
||||||
// TODO If this is ever modified, change application_id in debug/strings.xml
|
|
||||||
applicationIdSuffix = ".debug"
|
|
||||||
versionNameSuffix = "-debug"
|
|
||||||
isDebuggable = true
|
|
||||||
isJniDebuggable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
flavorDimensions.add("version")
|
|
||||||
productFlavors {
|
|
||||||
create("canary") {
|
|
||||||
dimension = "version"
|
|
||||||
applicationIdSuffix = ".canary"
|
|
||||||
}
|
|
||||||
|
|
||||||
create("nightly") {
|
|
||||||
dimension = "version"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
externalNativeBuild {
|
|
||||||
cmake {
|
|
||||||
version = "3.22.1"
|
|
||||||
path = file("../../../CMakeLists.txt")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
named("main") {
|
|
||||||
// Set up path for downloaded native libraries
|
|
||||||
jniLibs.srcDir(downloadedJniLibsPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
|
||||||
implementation("androidx.activity:activity-ktx:1.8.2")
|
|
||||||
implementation("androidx.fragment:fragment-ktx:1.6.2")
|
|
||||||
implementation("androidx.appcompat:appcompat:1.6.1")
|
|
||||||
implementation("androidx.documentfile:documentfile:1.0.1")
|
|
||||||
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0")
|
|
||||||
implementation("androidx.slidingpanelayout:slidingpanelayout:1.2.0")
|
|
||||||
implementation("com.google.android.material:material:1.9.0")
|
|
||||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
|
||||||
implementation("androidx.work:work-runtime:2.9.0")
|
|
||||||
implementation("org.ini4j:ini4j:0.5.4")
|
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
|
||||||
implementation("androidx.navigation:navigation-fragment-ktx:2.7.6")
|
|
||||||
implementation("androidx.navigation:navigation-ui-ktx:2.7.6")
|
|
||||||
implementation("info.debatty:java-string-similarity:2.0.0")
|
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")
|
|
||||||
implementation("androidx.preference:preference-ktx:1.2.1")
|
|
||||||
implementation("io.coil-kt:coil:2.5.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Download Vulkan Validation Layers from the KhronosGroup GitHub.
|
|
||||||
val downloadVulkanValidationLayers = tasks.register<Download>("downloadVulkanValidationLayers") {
|
|
||||||
src("https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/sdk-1.3.261.1/android-binaries-sdk-1.3.261.1-android.zip")
|
|
||||||
dest(file("${buildDir}/tmp/Vulkan-ValidationLayers.zip"))
|
|
||||||
onlyIfModified(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract Vulkan Validation Layers into the downloaded native libraries directory.
|
|
||||||
val unzipVulkanValidationLayers = tasks.register<Copy>("unzipVulkanValidationLayers") {
|
|
||||||
dependsOn(downloadVulkanValidationLayers)
|
|
||||||
from(zipTree(downloadVulkanValidationLayers.get().dest)) {
|
|
||||||
// Exclude the top level directory in the zip as it violates the expected jniLibs directory structure.
|
|
||||||
eachFile {
|
|
||||||
relativePath = RelativePath(true, *relativePath.segments.drop(1).toTypedArray())
|
|
||||||
}
|
|
||||||
includeEmptyDirs = false
|
|
||||||
}
|
|
||||||
into(downloadedJniLibsPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.named("preBuild") {
|
|
||||||
dependsOn(unzipVulkanValidationLayers)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGitVersion(): String {
|
|
||||||
var versionName = "0.0"
|
|
||||||
|
|
||||||
try {
|
|
||||||
versionName = ProcessBuilder("git", "describe", "--always", "--long")
|
|
||||||
.directory(project.rootDir)
|
|
||||||
.redirectOutput(ProcessBuilder.Redirect.PIPE)
|
|
||||||
.redirectError(ProcessBuilder.Redirect.PIPE)
|
|
||||||
.start().inputStream.bufferedReader().use { it.readText() }
|
|
||||||
.trim()
|
|
||||||
.replace(Regex("(-0)?-[^-]+$"), "")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logger.error("Cannot find git, defaulting to dummy version number")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (System.getenv("GITHUB_ACTIONS") != null) {
|
|
||||||
val gitTag = System.getenv("GIT_TAG_NAME")
|
|
||||||
versionName = gitTag ?: versionName
|
|
||||||
}
|
|
||||||
|
|
||||||
return versionName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGitHash(): String =
|
|
||||||
runGitCommand(ProcessBuilder("git", "rev-parse", "--short", "HEAD")) ?: "dummy-hash"
|
|
||||||
|
|
||||||
fun getBranch(): String =
|
|
||||||
runGitCommand(ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")) ?: "dummy-branch"
|
|
||||||
|
|
||||||
fun runGitCommand(command: ProcessBuilder) : String? {
|
|
||||||
try {
|
|
||||||
command.directory(project.rootDir)
|
|
||||||
val process = command.start()
|
|
||||||
val inputStream = process.inputStream
|
|
||||||
val errorStream = process.errorStream
|
|
||||||
process.waitFor()
|
|
||||||
|
|
||||||
return if (process.exitValue() == 0) {
|
|
||||||
inputStream.bufferedReader()
|
|
||||||
.use { it.readText().trim() } // return the value of gitHash
|
|
||||||
} else {
|
|
||||||
val errorMessage = errorStream.bufferedReader().use { it.readText().trim() }
|
|
||||||
logger.error("Error running git command: $errorMessage")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
logger.error("$e: Cannot find git")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
android.applicationVariants.configureEach {
|
|
||||||
val variant = this
|
|
||||||
val capitalizedName = variant.name.capitalizeUS()
|
|
||||||
|
|
||||||
val copyTask = tasks.register("copyBundle${capitalizedName}") {
|
|
||||||
doLast {
|
|
||||||
project.copy {
|
|
||||||
from(variant.outputs.first().outputFile.parentFile)
|
|
||||||
include("*.apk")
|
|
||||||
into(layout.buildDirectory.dir("bundle"))
|
|
||||||
}
|
|
||||||
project.copy {
|
|
||||||
from(layout.buildDirectory.dir("outputs/bundle/${variant.name}"))
|
|
||||||
include("*.aab")
|
|
||||||
into(layout.buildDirectory.dir("bundle"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasks.named("bundle${capitalizedName}").configure { finalizedBy(copyTask) }
|
|
||||||
}
|
|
40
src/android/app/proguard-rules.pro
vendored
40
src/android/app/proguard-rules.pro
vendored
|
@ -1,25 +1,21 @@
|
||||||
# Copyright 2023 Citra Emulator Project
|
# Add project specific ProGuard rules here.
|
||||||
# Licensed under GPLv2 or any later version
|
# You can control the set of applied configuration files using the
|
||||||
# Refer to the license.txt file included.
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
# To get usable stack traces
|
# If your project uses WebView with JS, uncomment the following
|
||||||
-dontobfuscate
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
# Prevents crashing when using Wini
|
# Uncomment this to preserve the line number information for
|
||||||
-keep class org.ini4j.spi.IniParser
|
# debugging stack traces.
|
||||||
-keep class org.ini4j.spi.IniBuilder
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
-keep class org.ini4j.spi.IniFormatter
|
|
||||||
|
|
||||||
# Suppress warnings for R8
|
# If you keep the line number information, uncomment this to
|
||||||
-dontwarn org.bouncycastle.jsse.BCSSLParameters
|
# hide the original source file name.
|
||||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
#-renamesourcefileattribute SourceFile
|
||||||
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
|
||||||
-dontwarn org.conscrypt.Conscrypt$Version
|
|
||||||
-dontwarn org.conscrypt.Conscrypt
|
|
||||||
-dontwarn org.conscrypt.ConscryptHostnameVerifier
|
|
||||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
|
||||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
|
||||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
|
||||||
-dontwarn java.beans.Introspector
|
|
||||||
-dontwarn java.beans.VetoableChangeListener
|
|
||||||
-dontwarn java.beans.VetoableChangeSupport
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.citra.citra_emu;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
public void useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
Context appContext = ApplicationProvider.getApplicationContext();
|
||||||
|
|
||||||
|
assertEquals("org.citra.citra_emu", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="org.citra.citra_emu">
|
||||||
<uses-feature
|
<uses-feature
|
||||||
android:name="android.hardware.touchscreen"
|
android:name="android.hardware.touchscreen"
|
||||||
android:required="false"/>
|
android:required="false"/>
|
||||||
|
@ -29,8 +30,6 @@
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="org.citra.citra_emu.CitraApplication"
|
android:name="org.citra.citra_emu.CitraApplication"
|
||||||
|
@ -42,13 +41,11 @@
|
||||||
android:banner="@mipmap/ic_launcher"
|
android:banner="@mipmap/ic_launcher"
|
||||||
android:requestLegacyExternalStorage="true">
|
android:requestLegacyExternalStorage="true">
|
||||||
|
|
||||||
<meta-data android:name="android.game_mode_config"
|
|
||||||
android:resource="@xml/game_mode_config" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.citra.citra_emu.ui.main.MainActivity"
|
android:name="org.citra.citra_emu.ui.main.MainActivity"
|
||||||
android:theme="@style/Theme.Citra.Splash.Main"
|
android:theme="@style/Theme.Citra.Splash.Main"
|
||||||
android:exported="true">
|
android:exported="true"
|
||||||
|
android:resizeableActivity="false">
|
||||||
|
|
||||||
<!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
|
<!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
@ -66,29 +63,25 @@
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.citra.citra_emu.activities.EmulationActivity"
|
android:name="org.citra.citra_emu.activities.EmulationActivity"
|
||||||
android:exported="true"
|
android:resizeableActivity="false"
|
||||||
android:theme="@style/Theme.Citra.Main"
|
android:theme="@style/Theme.Citra.Main"
|
||||||
android:launchMode="singleTop">
|
android:launchMode="singleTop"/>
|
||||||
|
|
||||||
<intent-filter>
|
<service android:name="org.citra.citra_emu.utils.ForegroundService"/>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<data
|
|
||||||
android:mimeType="application/octet-stream"
|
|
||||||
android:scheme="content" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<service android:name="org.citra.citra_emu.utils.ForegroundService" android:foregroundServiceType="specialUse">
|
|
||||||
<property android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE" android:value="Keep emulation running in background"/>
|
|
||||||
</service>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name="org.citra.citra_emu.features.cheats.ui.CheatsActivity"
|
android:name="org.citra.citra_emu.features.cheats.ui.CheatsActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:theme="@style/Theme.Citra.Main"
|
android:theme="@style/Theme.Citra.Main"
|
||||||
android:label="@string/cheats"/>
|
android:label="@string/cheats"/>
|
||||||
|
|
||||||
|
|
||||||
|
<provider
|
||||||
|
android:name="org.citra.citra_emu.model.GameProvider"
|
||||||
|
android:authorities="${applicationId}.provider"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false">
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Copyright 2019 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
package org.citra.citra_emu;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import org.citra.citra_emu.model.GameDatabase;
|
||||||
|
import org.citra.citra_emu.utils.DirectoryInitialization;
|
||||||
|
import org.citra.citra_emu.utils.DocumentsTree;
|
||||||
|
import org.citra.citra_emu.utils.PermissionsHandler;
|
||||||
|
|
||||||
|
public class CitraApplication extends Application {
|
||||||
|
public static GameDatabase databaseHelper;
|
||||||
|
public static DocumentsTree documentsTree;
|
||||||
|
private static CitraApplication application;
|
||||||
|
|
||||||
|
private void createNotificationChannel() {
|
||||||
|
// Create the NotificationChannel, but only on API 26+ because
|
||||||
|
// the NotificationChannel class is new and not in the support library
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NotificationManager notificationManager = getSystemService(NotificationManager.class);
|
||||||
|
{
|
||||||
|
// General notification
|
||||||
|
CharSequence name = getString(R.string.app_notification_channel_name);
|
||||||
|
String description = getString(R.string.app_notification_channel_description);
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
getString(R.string.app_notification_channel_id), name,
|
||||||
|
NotificationManager.IMPORTANCE_LOW);
|
||||||
|
channel.setDescription(description);
|
||||||
|
channel.setSound(null, null);
|
||||||
|
channel.setVibrationPattern(null);
|
||||||
|
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// CIA Install notifications
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
getString(R.string.cia_install_notification_channel_id),
|
||||||
|
getString(R.string.cia_install_notification_channel_name),
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
channel.setDescription(getString(R.string.cia_install_notification_channel_description));
|
||||||
|
channel.setSound(null, null);
|
||||||
|
channel.setVibrationPattern(null);
|
||||||
|
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
application = this;
|
||||||
|
documentsTree = new DocumentsTree();
|
||||||
|
|
||||||
|
if (PermissionsHandler.hasWriteAccess(getApplicationContext())) {
|
||||||
|
DirectoryInitialization.start(getApplicationContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeLibrary.LogDeviceInfo();
|
||||||
|
createNotificationChannel();
|
||||||
|
|
||||||
|
databaseHelper = new GameDatabase(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Context getAppContext() {
|
||||||
|
return application.getApplicationContext();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,81 +0,0 @@
|
||||||
// Copyright 2023 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
package org.citra.citra_emu
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Application
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.os.Build
|
|
||||||
import org.citra.citra_emu.utils.DirectoryInitialization
|
|
||||||
import org.citra.citra_emu.utils.DocumentsTree
|
|
||||||
import org.citra.citra_emu.utils.GpuDriverHelper
|
|
||||||
import org.citra.citra_emu.utils.PermissionsHandler
|
|
||||||
import org.citra.citra_emu.utils.Log
|
|
||||||
import org.citra.citra_emu.utils.MemoryUtil
|
|
||||||
|
|
||||||
class CitraApplication : Application() {
|
|
||||||
private fun createNotificationChannel() {
|
|
||||||
with(getSystemService(NotificationManager::class.java)) {
|
|
||||||
// General notification
|
|
||||||
val name: CharSequence = getString(R.string.app_notification_channel_name)
|
|
||||||
val description = getString(R.string.app_notification_channel_description)
|
|
||||||
val generalChannel = NotificationChannel(
|
|
||||||
getString(R.string.app_notification_channel_id),
|
|
||||||
name,
|
|
||||||
NotificationManager.IMPORTANCE_LOW
|
|
||||||
)
|
|
||||||
generalChannel.description = description
|
|
||||||
generalChannel.setSound(null, null)
|
|
||||||
generalChannel.vibrationPattern = null
|
|
||||||
createNotificationChannel(generalChannel)
|
|
||||||
|
|
||||||
// CIA Install notifications
|
|
||||||
val ciaChannel = NotificationChannel(
|
|
||||||
getString(R.string.cia_install_notification_channel_id),
|
|
||||||
getString(R.string.cia_install_notification_channel_name),
|
|
||||||
NotificationManager.IMPORTANCE_DEFAULT
|
|
||||||
)
|
|
||||||
ciaChannel.description =
|
|
||||||
getString(R.string.cia_install_notification_channel_description)
|
|
||||||
ciaChannel.setSound(null, null)
|
|
||||||
ciaChannel.vibrationPattern = null
|
|
||||||
createNotificationChannel(ciaChannel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
application = this
|
|
||||||
documentsTree = DocumentsTree()
|
|
||||||
if (PermissionsHandler.hasWriteAccess(applicationContext)) {
|
|
||||||
DirectoryInitialization.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeLibrary.logDeviceInfo()
|
|
||||||
logDeviceInfo()
|
|
||||||
createNotificationChannel()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun logDeviceInfo() {
|
|
||||||
Log.info("Device Manufacturer - ${Build.MANUFACTURER}")
|
|
||||||
Log.info("Device Model - ${Build.MODEL}")
|
|
||||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.R) {
|
|
||||||
Log.info("SoC Manufacturer - ${Build.SOC_MANUFACTURER}")
|
|
||||||
Log.info("SoC Model - ${Build.SOC_MODEL}")
|
|
||||||
}
|
|
||||||
Log.info("Total System Memory - ${MemoryUtil.getDeviceRAM()}")
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private var application: CitraApplication? = null
|
|
||||||
|
|
||||||
val appContext: Context get() = application!!.applicationContext
|
|
||||||
|
|
||||||
@SuppressLint("StaticFieldLeak")
|
|
||||||
lateinit var documentsTree: DocumentsTree
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,720 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2013 Dolphin Emulator Project
|
||||||
|
* Licensed under GPLv2+
|
||||||
|
* Refer to the license.txt file included.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.citra.citra_emu;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.view.Surface;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.core.content.ContextCompat;
|
||||||
|
import androidx.fragment.app.DialogFragment;
|
||||||
|
|
||||||
|
import org.citra.citra_emu.activities.EmulationActivity;
|
||||||
|
import org.citra.citra_emu.applets.SoftwareKeyboard;
|
||||||
|
import org.citra.citra_emu.utils.EmulationMenuSettings;
|
||||||
|
import org.citra.citra_emu.utils.FileUtil;
|
||||||
|
import org.citra.citra_emu.utils.Log;
|
||||||
|
import org.citra.citra_emu.utils.PermissionsHandler;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.CAMERA;
|
||||||
|
import static android.Manifest.permission.RECORD_AUDIO;
|
||||||
|
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class which contains methods that interact
|
||||||
|
* with the native side of the Citra code.
|
||||||
|
*/
|
||||||
|
public final class NativeLibrary {
|
||||||
|
/**
|
||||||
|
* Default touchscreen device
|
||||||
|
*/
|
||||||
|
public static final String TouchScreenDevice = "Touchscreen";
|
||||||
|
public static WeakReference<EmulationActivity> sEmulationActivity = new WeakReference<>(null);
|
||||||
|
|
||||||
|
private static boolean alertResult = false;
|
||||||
|
private static String alertPromptResult = "";
|
||||||
|
private static int alertPromptButton = 0;
|
||||||
|
private static final Object alertPromptLock = new Object();
|
||||||
|
private static boolean alertPromptInProgress = false;
|
||||||
|
private static String alertPromptCaption = "";
|
||||||
|
private static int alertPromptButtonConfig = 0;
|
||||||
|
private static EditText alertPromptEditText = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
System.loadLibrary("citra-android");
|
||||||
|
} catch (UnsatisfiedLinkError ex) {
|
||||||
|
Log.error("[NativeLibrary] " + ex.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NativeLibrary() {
|
||||||
|
// Disallows instantiation.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles button press events for a gamepad.
|
||||||
|
*
|
||||||
|
* @param Device The input descriptor of the gamepad.
|
||||||
|
* @param Button Key code identifying which button was pressed.
|
||||||
|
* @param Action Mask identifying which action is happening (button pressed down, or button released).
|
||||||
|
* @return If we handled the button press.
|
||||||
|
*/
|
||||||
|
public static native boolean onGamePadEvent(String Device, int Button, int Action);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles gamepad movement events.
|
||||||
|
*
|
||||||
|
* @param Device The device ID of the gamepad.
|
||||||
|
* @param Axis The axis ID
|
||||||
|
* @param x_axis The value of the x-axis represented by the given ID.
|
||||||
|
* @param y_axis The value of the y-axis represented by the given ID
|
||||||
|
*/
|
||||||
|
public static native boolean onGamePadMoveEvent(String Device, int Axis, float x_axis, float y_axis);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles gamepad movement events.
|
||||||
|
*
|
||||||
|
* @param Device The device ID of the gamepad.
|
||||||
|
* @param Axis_id The axis ID
|
||||||
|
* @param axis_val The value of the axis represented by the given ID.
|
||||||
|
*/
|
||||||
|
public static native boolean onGamePadAxisEvent(String Device, int Axis_id, float axis_val);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles touch events.
|
||||||
|
*
|
||||||
|
* @param x_axis The value of the x-axis.
|
||||||
|
* @param y_axis The value of the y-axis
|
||||||
|
* @param pressed To identify if the touch held down or released.
|
||||||
|
* @return true if the pointer is within the touchscreen
|
||||||
|
*/
|
||||||
|
public static native boolean onTouchEvent(float x_axis, float y_axis, boolean pressed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles touch movement.
|
||||||
|
*
|
||||||
|
* @param x_axis The value of the instantaneous x-axis.
|
||||||
|
* @param y_axis The value of the instantaneous y-axis.
|
||||||
|
*/
|
||||||
|
public static native void onTouchMoved(float x_axis, float y_axis);
|
||||||
|
|
||||||
|
public static native void ReloadSettings();
|
||||||
|
|
||||||
|
public static native String GetUserSetting(String gameID, String Section, String Key);
|
||||||
|
|
||||||
|
public static native void SetUserSetting(String gameID, String Section, String Key, String Value);
|
||||||
|
|
||||||
|
public static native void InitGameIni(String gameID);
|
||||||
|
|
||||||
|
public static native long GetTitleId(String filename);
|
||||||
|
|
||||||
|
public static native String GetGitRevision();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current working user directory
|
||||||
|
* If not set, it auto-detects a location
|
||||||
|
*/
|
||||||
|
public static native void SetUserDirectory(String directory);
|
||||||
|
|
||||||
|
public static native String[] GetInstalledGamePaths();
|
||||||
|
|
||||||
|
// Create the config.ini file.
|
||||||
|
public static native void CreateConfigFile();
|
||||||
|
|
||||||
|
public static native void CreateLogFile();
|
||||||
|
|
||||||
|
public static native void LogUserDirectory(String directory);
|
||||||
|
|
||||||
|
public static native int DefaultCPUCore();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins emulation.
|
||||||
|
*/
|
||||||
|
public static native void Run(String path);
|
||||||
|
|
||||||
|
public static native String[] GetTextureFilterNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Begins emulation from the specified savestate.
|
||||||
|
*/
|
||||||
|
public static native void Run(String path, String savestatePath, boolean deleteSavestate);
|
||||||
|
|
||||||
|
// Surface Handling
|
||||||
|
public static native void SurfaceChanged(Surface surf);
|
||||||
|
|
||||||
|
public static native void SurfaceDestroyed();
|
||||||
|
|
||||||
|
public static native void DoFrame();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unpauses emulation from a paused state.
|
||||||
|
*/
|
||||||
|
public static native void UnPauseEmulation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pauses emulation.
|
||||||
|
*/
|
||||||
|
public static native void PauseEmulation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops emulation.
|
||||||
|
*/
|
||||||
|
public static native void StopEmulation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if emulation is running (or is paused).
|
||||||
|
*/
|
||||||
|
public static native boolean IsRunning();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the title ID of the currently running title, or 0 on failure.
|
||||||
|
*/
|
||||||
|
public static native long GetRunningTitleId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the performance stats for the current game
|
||||||
|
**/
|
||||||
|
public static native double[] GetPerfStats();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies the core emulation that the orientation has changed.
|
||||||
|
*/
|
||||||
|
public static native void NotifyOrientationChange(int layout_option, int rotation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps the top and bottom screens.
|
||||||
|
*/
|
||||||
|
public static native void SwapScreens(boolean swap_screens, int rotation);
|
||||||
|
|
||||||
|
public enum CoreError {
|
||||||
|
ErrorSystemFiles,
|
||||||
|
ErrorSavestate,
|
||||||
|
ErrorUnknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean coreErrorAlertResult = false;
|
||||||
|
private static final Object coreErrorAlertLock = new Object();
|
||||||
|
|
||||||
|
public static class CoreErrorDialogFragment extends DialogFragment {
|
||||||
|
static CoreErrorDialogFragment newInstance(String title, String message) {
|
||||||
|
CoreErrorDialogFragment frag = new CoreErrorDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString("title", title);
|
||||||
|
args.putString("message", message);
|
||||||
|
frag.setArguments(args);
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Activity emulationActivity = Objects.requireNonNull(getActivity());
|
||||||
|
|
||||||
|
final String title = Objects.requireNonNull(Objects.requireNonNull(getArguments()).getString("title"));
|
||||||
|
final String message = Objects.requireNonNull(Objects.requireNonNull(getArguments()).getString("message"));
|
||||||
|
|
||||||
|
return new MaterialAlertDialogBuilder(emulationActivity)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(R.string.continue_button, (dialog, which) -> {
|
||||||
|
coreErrorAlertResult = true;
|
||||||
|
synchronized (coreErrorAlertLock) {
|
||||||
|
coreErrorAlertLock.notify();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(R.string.abort_button, (dialog, which) -> {
|
||||||
|
coreErrorAlertResult = false;
|
||||||
|
synchronized (coreErrorAlertLock) {
|
||||||
|
coreErrorAlertLock.notify();
|
||||||
|
}
|
||||||
|
}).setOnDismissListener(dialog -> {
|
||||||
|
coreErrorAlertResult = true;
|
||||||
|
synchronized (coreErrorAlertLock) {
|
||||||
|
coreErrorAlertLock.notify();
|
||||||
|
}
|
||||||
|
}).create();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnCoreErrorImpl(String title, String message) {
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.error("[NativeLibrary] EmulationActivity not present");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoreErrorDialogFragment fragment = CoreErrorDialogFragment.newInstance(title, message);
|
||||||
|
fragment.show(emulationActivity.getSupportFragmentManager(), "coreError");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a core error.
|
||||||
|
* @return true: continue; false: abort
|
||||||
|
*/
|
||||||
|
public static boolean OnCoreError(CoreError error, String details) {
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.error("[NativeLibrary] EmulationActivity not present");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
String title, message;
|
||||||
|
switch (error) {
|
||||||
|
case ErrorSystemFiles: {
|
||||||
|
title = emulationActivity.getString(R.string.system_archive_not_found);
|
||||||
|
message = emulationActivity.getString(R.string.system_archive_not_found_message, details.isEmpty() ? emulationActivity.getString(R.string.system_archive_general) : details);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ErrorSavestate: {
|
||||||
|
title = emulationActivity.getString(R.string.save_load_error);
|
||||||
|
message = details;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ErrorUnknown: {
|
||||||
|
title = emulationActivity.getString(R.string.fatal_error);
|
||||||
|
message = emulationActivity.getString(R.string.fatal_error_message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the AlertDialog on the main thread.
|
||||||
|
emulationActivity.runOnUiThread(() -> OnCoreErrorImpl(title, message));
|
||||||
|
|
||||||
|
// Wait for the lock to notify that it is complete.
|
||||||
|
synchronized (coreErrorAlertLock) {
|
||||||
|
try {
|
||||||
|
coreErrorAlertLock.wait();
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coreErrorAlertResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPortraitMode() {
|
||||||
|
return CitraApplication.getAppContext().getResources().getConfiguration().orientation ==
|
||||||
|
Configuration.ORIENTATION_PORTRAIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int landscapeScreenLayout() {
|
||||||
|
return EmulationMenuSettings.getLandscapeScreenLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean displayAlertMsg(final String caption, final String text,
|
||||||
|
final boolean yesNo) {
|
||||||
|
Log.error("[NativeLibrary] Alert: " + text);
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
boolean result = false;
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.warning("[NativeLibrary] EmulationActivity is null, can't do panic alert.");
|
||||||
|
} else {
|
||||||
|
// Create object used for waiting.
|
||||||
|
final Object lock = new Object();
|
||||||
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
|
||||||
|
.setTitle(caption)
|
||||||
|
.setMessage(text);
|
||||||
|
|
||||||
|
// If not yes/no dialog just have one button that dismisses modal,
|
||||||
|
// otherwise have a yes and no button that sets alertResult accordingly.
|
||||||
|
if (!yesNo) {
|
||||||
|
builder
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton(android.R.string.ok, (dialog, whichButton) ->
|
||||||
|
{
|
||||||
|
dialog.dismiss();
|
||||||
|
synchronized (lock) {
|
||||||
|
lock.notify();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
alertResult = false;
|
||||||
|
|
||||||
|
builder
|
||||||
|
.setPositiveButton(android.R.string.yes, (dialog, whichButton) ->
|
||||||
|
{
|
||||||
|
alertResult = true;
|
||||||
|
dialog.dismiss();
|
||||||
|
synchronized (lock) {
|
||||||
|
lock.notify();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton(android.R.string.no, (dialog, whichButton) ->
|
||||||
|
{
|
||||||
|
alertResult = false;
|
||||||
|
dialog.dismiss();
|
||||||
|
synchronized (lock) {
|
||||||
|
lock.notify();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the AlertDialog on the main thread.
|
||||||
|
emulationActivity.runOnUiThread(builder::show);
|
||||||
|
|
||||||
|
// Wait for the lock to notify that it is complete.
|
||||||
|
synchronized (lock) {
|
||||||
|
try {
|
||||||
|
lock.wait();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yesNo)
|
||||||
|
result = alertResult;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void retryDisplayAlertPrompt() {
|
||||||
|
if (!alertPromptInProgress) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
displayAlertPromptImpl(alertPromptCaption, alertPromptEditText.getText().toString(), alertPromptButtonConfig).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String displayAlertPrompt(String caption, String text, int buttonConfig) {
|
||||||
|
alertPromptCaption = caption;
|
||||||
|
alertPromptButtonConfig = buttonConfig;
|
||||||
|
alertPromptInProgress = true;
|
||||||
|
|
||||||
|
// Show the AlertDialog on the main thread
|
||||||
|
sEmulationActivity.get().runOnUiThread(() -> displayAlertPromptImpl(alertPromptCaption, text, alertPromptButtonConfig).show());
|
||||||
|
|
||||||
|
// Wait for the lock to notify that it is complete
|
||||||
|
synchronized (alertPromptLock) {
|
||||||
|
try {
|
||||||
|
alertPromptLock.wait();
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alertPromptInProgress = false;
|
||||||
|
|
||||||
|
return alertPromptResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MaterialAlertDialogBuilder displayAlertPromptImpl(String caption, String text, int buttonConfig) {
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
alertPromptResult = "";
|
||||||
|
alertPromptButton = 0;
|
||||||
|
|
||||||
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
params.leftMargin = params.rightMargin = CitraApplication.getAppContext().getResources().getDimensionPixelSize(R.dimen.dialog_margin);
|
||||||
|
|
||||||
|
// Set up the input
|
||||||
|
alertPromptEditText = new EditText(CitraApplication.getAppContext());
|
||||||
|
alertPromptEditText.setText(text);
|
||||||
|
alertPromptEditText.setSingleLine();
|
||||||
|
alertPromptEditText.setLayoutParams(params);
|
||||||
|
|
||||||
|
FrameLayout container = new FrameLayout(emulationActivity);
|
||||||
|
container.addView(alertPromptEditText);
|
||||||
|
|
||||||
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
|
||||||
|
.setTitle(caption)
|
||||||
|
.setView(container)
|
||||||
|
.setPositiveButton(android.R.string.ok, (dialogInterface, i) ->
|
||||||
|
{
|
||||||
|
alertPromptButton = buttonConfig;
|
||||||
|
alertPromptResult = alertPromptEditText.getText().toString();
|
||||||
|
synchronized (alertPromptLock) {
|
||||||
|
alertPromptLock.notifyAll();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setOnDismissListener(dialogInterface ->
|
||||||
|
{
|
||||||
|
alertPromptResult = "";
|
||||||
|
synchronized (alertPromptLock) {
|
||||||
|
alertPromptLock.notifyAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (buttonConfig > 0) {
|
||||||
|
builder.setNegativeButton(android.R.string.cancel, (dialogInterface, i) ->
|
||||||
|
{
|
||||||
|
alertPromptResult = "";
|
||||||
|
synchronized (alertPromptLock) {
|
||||||
|
alertPromptLock.notifyAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int alertPromptButton() {
|
||||||
|
return alertPromptButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void exitEmulationActivity(int resultCode) {
|
||||||
|
final int Success = 0;
|
||||||
|
final int ErrorNotInitialized = 1;
|
||||||
|
final int ErrorGetLoader = 2;
|
||||||
|
final int ErrorSystemMode = 3;
|
||||||
|
final int ErrorLoader = 4;
|
||||||
|
final int ErrorLoader_ErrorEncrypted = 5;
|
||||||
|
final int ErrorLoader_ErrorInvalidFormat = 6;
|
||||||
|
final int ErrorSystemFiles = 7;
|
||||||
|
final int ShutdownRequested = 11;
|
||||||
|
final int ErrorUnknown = 12;
|
||||||
|
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.warning("[NativeLibrary] EmulationActivity is null, can't exit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int captionId = R.string.loader_error_invalid_format;
|
||||||
|
if (resultCode == ErrorLoader_ErrorEncrypted) {
|
||||||
|
captionId = R.string.loader_error_encrypted;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
|
||||||
|
.setTitle(captionId)
|
||||||
|
.setMessage(Html.fromHtml("Please follow the guides to redump your <a href=\"https://citra-emu.org/wiki/dumping-game-cartridges/\">game cartidges</a> or <a href=\"https://citra-emu.org/wiki/dumping-installed-titles/\">installed titles</a>.", Html.FROM_HTML_MODE_LEGACY))
|
||||||
|
.setPositiveButton(android.R.string.ok, (dialog, whichButton) -> emulationActivity.finish())
|
||||||
|
.setOnDismissListener(dialogInterface -> emulationActivity.finish());
|
||||||
|
emulationActivity.runOnUiThread(() -> {
|
||||||
|
AlertDialog alert = builder.create();
|
||||||
|
alert.show();
|
||||||
|
((TextView) alert.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEmulationActivity(EmulationActivity emulationActivity) {
|
||||||
|
Log.verbose("[NativeLibrary] Registering EmulationActivity.");
|
||||||
|
sEmulationActivity = new WeakReference<>(emulationActivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearEmulationActivity() {
|
||||||
|
Log.verbose("[NativeLibrary] Unregistering EmulationActivity.");
|
||||||
|
|
||||||
|
sEmulationActivity.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object cameraPermissionLock = new Object();
|
||||||
|
private static boolean cameraPermissionGranted = false;
|
||||||
|
public static final int REQUEST_CODE_NATIVE_CAMERA = 800;
|
||||||
|
|
||||||
|
public static boolean RequestCameraPermission() {
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.error("[NativeLibrary] EmulationActivity not present");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ContextCompat.checkSelfPermission(emulationActivity, CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Permission already granted
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
emulationActivity.requestPermissions(new String[]{CAMERA}, REQUEST_CODE_NATIVE_CAMERA);
|
||||||
|
|
||||||
|
// Wait until result is returned
|
||||||
|
synchronized (cameraPermissionLock) {
|
||||||
|
try {
|
||||||
|
cameraPermissionLock.wait();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cameraPermissionGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CameraPermissionResult(boolean granted) {
|
||||||
|
cameraPermissionGranted = granted;
|
||||||
|
synchronized (cameraPermissionLock) {
|
||||||
|
cameraPermissionLock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object micPermissionLock = new Object();
|
||||||
|
private static boolean micPermissionGranted = false;
|
||||||
|
public static final int REQUEST_CODE_NATIVE_MIC = 900;
|
||||||
|
|
||||||
|
public static boolean RequestMicPermission() {
|
||||||
|
final EmulationActivity emulationActivity = sEmulationActivity.get();
|
||||||
|
if (emulationActivity == null) {
|
||||||
|
Log.error("[NativeLibrary] EmulationActivity not present");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ContextCompat.checkSelfPermission(emulationActivity, RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
// Permission already granted
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
emulationActivity.requestPermissions(new String[]{RECORD_AUDIO}, REQUEST_CODE_NATIVE_MIC);
|
||||||
|
|
||||||
|
// Wait until result is returned
|
||||||
|
synchronized (micPermissionLock) {
|
||||||
|
try {
|
||||||
|
micPermissionLock.wait();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return micPermissionGranted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MicPermissionResult(boolean granted) {
|
||||||
|
micPermissionGranted = granted;
|
||||||
|
synchronized (micPermissionLock) {
|
||||||
|
micPermissionLock.notify();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Notifies that the activity is now in foreground and camera devices can now be reloaded
|
||||||
|
public static native void ReloadCameraDevices();
|
||||||
|
|
||||||
|
public static native boolean LoadAmiibo(byte[] bytes);
|
||||||
|
|
||||||
|
public static native void RemoveAmiibo();
|
||||||
|
|
||||||
|
public static final int SAVESTATE_SLOT_COUNT = 10;
|
||||||
|
|
||||||
|
public static final class SavestateInfo {
|
||||||
|
public int slot;
|
||||||
|
public Date time;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static native SavestateInfo[] GetSavestateInfo();
|
||||||
|
|
||||||
|
public static native void SaveState(int slot);
|
||||||
|
public static native void LoadState(int slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs the Citra version, Android version and, CPU.
|
||||||
|
*/
|
||||||
|
public static native void LogDeviceInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button type for use in onTouchEvent
|
||||||
|
*/
|
||||||
|
public static final class ButtonType {
|
||||||
|
public static final int BUTTON_A = 700;
|
||||||
|
public static final int BUTTON_B = 701;
|
||||||
|
public static final int BUTTON_X = 702;
|
||||||
|
public static final int BUTTON_Y = 703;
|
||||||
|
public static final int BUTTON_START = 704;
|
||||||
|
public static final int BUTTON_SELECT = 705;
|
||||||
|
public static final int BUTTON_HOME = 706;
|
||||||
|
public static final int BUTTON_ZL = 707;
|
||||||
|
public static final int BUTTON_ZR = 708;
|
||||||
|
public static final int DPAD_UP = 709;
|
||||||
|
public static final int DPAD_DOWN = 710;
|
||||||
|
public static final int DPAD_LEFT = 711;
|
||||||
|
public static final int DPAD_RIGHT = 712;
|
||||||
|
public static final int STICK_LEFT = 713;
|
||||||
|
public static final int STICK_LEFT_UP = 714;
|
||||||
|
public static final int STICK_LEFT_DOWN = 715;
|
||||||
|
public static final int STICK_LEFT_LEFT = 716;
|
||||||
|
public static final int STICK_LEFT_RIGHT = 717;
|
||||||
|
public static final int STICK_C = 718;
|
||||||
|
public static final int STICK_C_UP = 719;
|
||||||
|
public static final int STICK_C_DOWN = 720;
|
||||||
|
public static final int STICK_C_LEFT = 771;
|
||||||
|
public static final int STICK_C_RIGHT = 772;
|
||||||
|
public static final int TRIGGER_L = 773;
|
||||||
|
public static final int TRIGGER_R = 774;
|
||||||
|
public static final int DPAD = 780;
|
||||||
|
public static final int BUTTON_DEBUG = 781;
|
||||||
|
public static final int BUTTON_GPIO14 = 782;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Button states
|
||||||
|
*/
|
||||||
|
public static final class ButtonState {
|
||||||
|
public static final int RELEASED = 0;
|
||||||
|
public static final int PRESSED = 1;
|
||||||
|
}
|
||||||
|
public static boolean createFile(String directory, String filename) {
|
||||||
|
if (FileUtil.isNativePath(directory)) {
|
||||||
|
return CitraApplication.documentsTree.createFile(directory, filename);
|
||||||
|
}
|
||||||
|
return FileUtil.createFile(CitraApplication.getAppContext(), directory, filename) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean createDir(String directory, String directoryName) {
|
||||||
|
if (FileUtil.isNativePath(directory)) {
|
||||||
|
return CitraApplication.documentsTree.createDir(directory, directoryName);
|
||||||
|
}
|
||||||
|
return FileUtil.createDir(CitraApplication.getAppContext(), directory, directoryName) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int openContentUri(String path, String openMode) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.openContentUri(path, openMode);
|
||||||
|
}
|
||||||
|
return FileUtil.openContentUri(CitraApplication.getAppContext(), path, openMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getFilesName(String path) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.getFilesName(path);
|
||||||
|
}
|
||||||
|
return FileUtil.getFilesName(CitraApplication.getAppContext(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long getSize(String path) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.getFileSize(path);
|
||||||
|
}
|
||||||
|
return FileUtil.getFileSize(CitraApplication.getAppContext(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean fileExists(String path) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.Exists(path);
|
||||||
|
}
|
||||||
|
return FileUtil.Exists(CitraApplication.getAppContext(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDirectory(String path) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.isDirectory(path);
|
||||||
|
}
|
||||||
|
return FileUtil.isDirectory(CitraApplication.getAppContext(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean copyFile(String sourcePath, String destinationParentPath, String destinationFilename) {
|
||||||
|
if (FileUtil.isNativePath(sourcePath) && FileUtil.isNativePath(destinationParentPath)) {
|
||||||
|
return CitraApplication.documentsTree.copyFile(sourcePath, destinationParentPath, destinationFilename);
|
||||||
|
}
|
||||||
|
return FileUtil.copyFile(CitraApplication.getAppContext(), sourcePath, destinationParentPath, destinationFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean renameFile(String path, String destinationFilename) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.renameFile(path, destinationFilename);
|
||||||
|
}
|
||||||
|
return FileUtil.renameFile(CitraApplication.getAppContext(), path, destinationFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deleteDocument(String path) {
|
||||||
|
if (FileUtil.isNativePath(path)) {
|
||||||
|
return CitraApplication.documentsTree.deleteDocument(path);
|
||||||
|
}
|
||||||
|
return FileUtil.deleteDocument(CitraApplication.getAppContext(), path);
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue