Revert "Merge pull request #129 from libretro/revert-127-vulkan"

This reverts commit 2d67658e85, reversing
changes made to 0d53ec6258.
This commit is contained in:
Eric Warmenhoven 2024-01-24 11:55:52 -05:00 committed by Eric Warmenhoven
parent 51d6e3bb88
commit b83b5e4b44
1798 changed files with 201082 additions and 117836 deletions

22
.ci/android.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/bash -ex
export NDK_CCACHE=$(which ccache)
[ "$GITHUB_REPOSITORY" = "citra-emu/citra-canary" ] &&
BUILD_FLAVOR=canary ||
BUILD_FLAVOR=nightly
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
export ANDROID_KEYSTORE_FILE="${GITHUB_WORKSPACE}/ks.jks"
base64 --decode <<< "${ANDROID_KEYSTORE_B64}" > "${ANDROID_KEYSTORE_FILE}"
fi
cd src/android
chmod +x ./gradlew
./gradlew assemble${BUILD_FLAVOR}Release
./gradlew bundle${BUILD_FLAVOR}Release
ccache -s -v
if [ ! -z "${ANDROID_KEYSTORE_B64}" ]; then
rm "${ANDROID_KEYSTORE_FILE}"
fi

View File

@ -7,7 +7,7 @@ if grep -nrI '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .ci* dis
fi
# Default clang-format points to default 3.5 version one
CLANG_FORMAT=clang-format-10
CLANG_FORMAT=clang-format-15
$CLANG_FORMAT --version
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then

View File

@ -1,28 +0,0 @@
#!/bin/bash -ex
# Copy documentation
cp license.txt "$REV_NAME"
cp README.md "$REV_NAME"
# Copy cross-platform scripting support
cp -r dist/scripting "$REV_NAME"
tar $COMPRESSION_FLAGS "$ARCHIVE_NAME" "$REV_NAME"
# Find out what release we are building
if [ -z $GIT_TAG_NAME ]; then
RELEASE_NAME=head
else
RELEASE_NAME=$(echo $GIT_TAG_NAME | cut -d- -f1)
if [ "$NAME" = "linux-mingw" ]; then
RELEASE_NAME="${RELEASE_NAME}-mingw"
fi
fi
mv "$REV_NAME" $RELEASE_NAME
7z a "$REV_NAME.7z" $RELEASE_NAME
# move the compiled archive into the artifacts directory to be uploaded by travis releases
mv "$ARCHIVE_NAME" artifacts/
mv "$REV_NAME.7z" artifacts/

View File

@ -1,6 +0,0 @@
#!/bin/bash -ex
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
mkdir -p artifacts

15
.ci/ios.sh Executable file
View File

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

View File

@ -1,3 +0,0 @@
#!/bin/bash -ex
mkdir -p "$HOME/.ccache"
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-clang-format /bin/bash -ex /citra/.ci/clang-format/docker.sh

View File

@ -1,4 +0,0 @@
#!/bin/bash -ex
# Run clang-format
./.ci/linux-clang-format/script.sh

View File

@ -1,3 +0,0 @@
#!/bin/bash -ex
mkdir -p "$HOME/.ccache"
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-fresh /bin/bash -ex /citra/.ci/linux/docker.sh

View File

@ -1,7 +0,0 @@
#!/bin/bash -ex
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON
ninja
ctest -VV -C Release

View File

@ -1,19 +0,0 @@
#!/bin/bash -ex
. .ci/common/pre-upload.sh
REV_NAME="citra-linux-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.xz"
COMPRESSION_FLAGS="-cJvf"
mkdir "$REV_NAME"
cp build/bin/Release/citra "$REV_NAME"
cp build/bin/Release/citra-room "$REV_NAME"
cp build/bin/Release/citra-qt "$REV_NAME"
# We need icons on Linux for .desktop entries
mkdir "$REV_NAME/dist"
cp dist/icon.png "$REV_NAME/dist/citra.png"
. .ci/common/post-upload.sh

View File

@ -1,3 +0,0 @@
#!/bin/bash -ex
mkdir -p "$HOME/.ccache"
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-frozen /bin/bash -ex /citra/.ci/linux-frozen/docker.sh

View File

@ -1,15 +0,0 @@
#!/bin/bash -ex
mkdir -p ~/bin/gold
echo '#!/bin/bash' > ~/bin/gold/ld
echo 'gold "$@"' >> ~/bin/gold/ld
chmod a+x ~/bin/gold/ld
export CFLAGS="-B$HOME/bin/gold $CFLAGS"
export CXXFLAGS="-B$HOME/bin/gold $CXXFLAGS"
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++
ninja
ctest -VV -C Release

View File

@ -1,52 +0,0 @@
#!/usr/bin/python
import sys
import re
import subprocess
from launchpadlib.launchpad import Launchpad
if sys.version_info[0] > 2:
xrange = range
cachedir = '/.launchpadlib/cache/'
launchpad = Launchpad.login_anonymously(
'grab build info', 'production', cachedir, version='devel')
processed_packages = []
deb_file_list = []
def get_url(pkg, distro):
build_ref = launchpad.archives.getByReference(reference='ubuntu').getPublishedBinaries(
binary_name=pkg[0], distro_arch_series='https://api.launchpad.net/devel/ubuntu/' + distro + '/amd64', version=pkg[1], exact_match=True, order_by_date=True).entries[0]
build_link = build_ref['build_link']
deb_name = '{}_{}_{}.deb'.format(pkg[0], pkg[1], 'amd64' if build_ref['architecture_specific'] else 'all')
deb_link = build_link + '/+files/' + deb_name
return [deb_link, deb_name]
def list_dependencies(deb_file):
t = subprocess.check_output(
['bash', '-c', '(dpkg -I {} | grep -oP "^ Depends\: \K.*$") || true'.format(deb_file)])
deps = [i.strip() for i in t.split(',')]
equals_re = re.compile(r'^(.*) \(= (.*)\)$')
return [equals_re.sub(r'\1=\2', i).split('=') for i in filter(equals_re.match, deps)]
def get_package(pkg, distro):
if pkg in processed_packages:
return
print('Getting {}...'.format(pkg[0]))
url = get_url(pkg, distro)
subprocess.check_call(['wget', '--quiet', url[0], '-O', url[1]])
for dep in list_dependencies(url[1]):
get_package(dep, distro)
processed_packages.append(pkg)
deb_file_list.append('./' + url[1])
for i in xrange(1, len(sys.argv), 3):
get_package([sys.argv[i], sys.argv[i + 1]], sys.argv[i + 2])
subprocess.check_call(
['apt-get', 'install', '-y', '--force-yes'] + deb_file_list)

View File

@ -1,3 +0,0 @@
#!/bin/bash -ex
mkdir "$HOME/.ccache" || true
docker run -v $(pwd):/citra -v "$HOME/.ccache":/root/.ccache citraemu/build-environments:linux-mingw /bin/bash -ex /citra/.ci/linux-mingw/docker.sh

View File

@ -1,30 +0,0 @@
#!/bin/bash -ex
# override CI ccache size
mkdir -p "$HOME/.ccache/"
echo 'max_size = 3.0G' > "$HOME/.ccache/ccache.conf"
mkdir build && cd build
cmake .. -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MinGWCross.cmake" -DUSE_CCACHE=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_MF=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON -DCMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE -DCOMPILE_WITH_DWARF=OFF
ninja
echo "Tests skipped"
#ctest -VV -C Release
ccache -s
echo 'Prepare binaries...'
cd ..
mkdir package
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
find build/ -name "citra*.exe" -exec cp {} 'package' \;
# copy Qt plugins
mkdir package/platforms
cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/
cp -rv "${QT_PLATFORM_DLL_PATH}/../mediaservice/" package/
cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
rm -f package/mediaservice/*d.dll
python3 .ci/linux-mingw/scan_dll.py package/*.exe package/imageformats/*.dll "package/"

View File

@ -1,122 +0,0 @@
try:
import lief
except ImportError:
import pefile
import sys
import re
import os
import queue
import shutil
# constant definitions
KNOWN_SYS_DLLS = ['WINMM.DLL', 'MSVCRT.DLL', 'VERSION.DLL', 'MPR.DLL',
'DWMAPI.DLL', 'UXTHEME.DLL', 'DNSAPI.DLL', 'IPHLPAPI.DLL']
# below is for Ubuntu 18.04 with specified PPA enabled, if you are using
# other distro or different repositories, change the following accordingly
DLL_PATH = [
'/usr/x86_64-w64-mingw32/bin/',
'/usr/x86_64-w64-mingw32/lib/',
'/usr/lib/gcc/x86_64-w64-mingw32/9.3-posix/'
]
missing = []
def parse_imports_lief(filename):
results = []
pe = lief.parse(filename)
for entry in pe.imports:
name = entry.name
if name.upper() not in KNOWN_SYS_DLLS and not re.match(string=name, pattern=r'.*32\.DLL'):
results.append(name)
return results
def parse_imports(file_name):
if globals().get('lief'):
return parse_imports_lief(file_name)
results = []
pe = pefile.PE(file_name, fast_load=True)
pe.parse_data_directories()
for entry in pe.DIRECTORY_ENTRY_IMPORT:
current = entry.dll.decode()
current_u = current.upper() # b/c Windows is often case insensitive
# here we filter out system dlls
# dll w/ names like *32.dll are likely to be system dlls
if current_u.upper() not in KNOWN_SYS_DLLS and not re.match(string=current_u, pattern=r'.*32\.DLL'):
results.append(current)
return results
def parse_imports_recursive(file_name, path_list=[]):
q = queue.Queue() # create a FIFO queue
# file_name can be a string or a list for the convience
if isinstance(file_name, str):
q.put(file_name)
elif isinstance(file_name, list):
for i in file_name:
q.put(i)
full_list = []
while q.qsize():
current = q.get_nowait()
print('> %s' % current)
deps = parse_imports(current)
# if this dll does not have any import, ignore it
if not deps:
continue
for dep in deps:
# the dependency already included in the list, skip
if dep in full_list:
continue
# find the requested dll in the provided paths
full_path = find_dll(dep)
if not full_path:
missing.append(dep)
continue
full_list.append(dep)
q.put(full_path)
path_list.append(full_path)
return full_list
def find_dll(name):
for path in DLL_PATH:
for root, _, files in os.walk(path):
for f in files:
if name.lower() == f.lower():
return os.path.join(root, f)
def deploy(name, dst, dry_run=False):
dlls_path = []
parse_imports_recursive(name, dlls_path)
for dll_entry in dlls_path:
if not dry_run:
shutil.copy(dll_entry, dst)
else:
print('[Dry-Run] Copy %s to %s' % (dll_entry, dst))
print('Deploy completed.')
return dlls_path
def main():
if len(sys.argv) < 3:
print('Usage: %s [files to examine ...] [target deploy directory]')
return 1
to_deploy = sys.argv[1:-1]
tgt_dir = sys.argv[-1]
if not os.path.isdir(tgt_dir):
print('%s is not a directory.' % tgt_dir)
return 1
print('Scanning dependencies...')
deploy(to_deploy, tgt_dir)
if missing:
print('Following DLLs are not found: %s' % ('\n'.join(missing)))
return 0
if __name__ == '__main__':
main()

View File

@ -1,13 +0,0 @@
#!/bin/bash -ex
. .ci/common/pre-upload.sh
REV_NAME="citra-windows-mingw-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.gz"
COMPRESSION_FLAGS="-czvf"
mkdir "$REV_NAME"
# get around the permission issues
cp -r package/* "$REV_NAME"
. .ci/common/post-upload.sh

27
.ci/linux.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash -ex
if [ "$TARGET" = "appimage" ]; then
export COMPILER_FLAGS=(-DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang -DCMAKE_LINKER=/etc/bin/ld.lld)
fi
mkdir build && cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
"${COMPILER_FLAGS[@]}" \
-DENABLE_QT_TRANSLATION=ON \
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DUSE_DISCORD_PRESENCE=ON
ninja
if [ "$TARGET" = "appimage" ]; then
ninja bundle
# TODO: Our AppImage environment currently uses an older ccache version without the verbose flag.
ccache -s
else
ccache -s -v
fi
ctest -VV -C Release

43
.ci/macos-universal.sh Executable file
View File

@ -0,0 +1,43 @@
#!/bin/bash -ex
ARTIFACTS_LIST=($ARTIFACTS)
BUNDLE_DIR=build/bundle
mkdir build
# Set up the base artifact to combine into.
BASE_ARTIFACT=${ARTIFACTS_LIST[0]}
BASE_ARTIFACT_ARCH="${BASE_ARTIFACT##*-}"
mv $BASE_ARTIFACT $BUNDLE_DIR
# Executable binary paths that need to be combined.
BIN_PATHS=(citra citra-room citra-qt.app/Contents/MacOS/citra-qt)
# Dylib paths that need to be combined.
IFS=$'\n'
DYLIB_PATHS=($(cd $BUNDLE_DIR && find . -name '*.dylib'))
unset IFS
# Combine all of the executable binaries and dylibs.
for OTHER_ARTIFACT in "${ARTIFACTS_LIST[@]:1}"; do
OTHER_ARTIFACT_ARCH="${OTHER_ARTIFACT##*-}"
for BIN_PATH in "${BIN_PATHS[@]}"; do
lipo -create -output $BUNDLE_DIR/$BIN_PATH $BUNDLE_DIR/$BIN_PATH $OTHER_ARTIFACT/$BIN_PATH
done
for DYLIB_PATH in "${DYLIB_PATHS[@]}"; do
# Only merge if the libraries do not have conflicting arches, otherwise it will fail.
DYLIB_INFO=`file $BUNDLE_DIR/$DYLIB_PATH`
OTHER_DYLIB_INFO=`file $OTHER_ARTIFACT/$DYLIB_PATH`
if ! [[ "$DYLIB_INFO" =~ "$OTHER_ARTIFACT_ARCH" ]] && ! [[ "$OTHER_DYLIB_INFO" =~ "$BASE_ARTIFACT_ARCH" ]]; then
lipo -create -output $BUNDLE_DIR/$DYLIB_PATH $BUNDLE_DIR/$DYLIB_PATH $OTHER_ARTIFACT/$DYLIB_PATH
fi
done
done
# Re-sign executables and bundles after combining.
APP_PATHS=(citra citra-room citra-qt.app)
for APP_PATH in "${APP_PATHS[@]}"; do
codesign --deep -fs - $BUNDLE_DIR/$APP_PATH
done

21
.ci/macos.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash -ex
mkdir build && cd build
cmake .. -GNinja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_ARCHITECTURES="$TARGET" \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DENABLE_QT_TRANSLATION=ON \
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DUSE_DISCORD_PRESENCE=ON
ninja
ninja bundle
ccache -s -v
CURRENT_ARCH=`arch`
if [ "$TARGET" = "$CURRENT_ARCH" ]; then
ctest -VV -C Release
fi

View File

@ -1,29 +0,0 @@
#!/bin/bash -ex
set -o pipefail
export Qt5_DIR=$(brew --prefix)/opt/qt5
export PATH="/usr/local/opt/ccache/libexec:$PATH"
# ccache configurations
export CCACHE_CPP2=yes
export CCACHE_SLOPPINESS=time_macros
export CC="ccache clang"
export CXX="ccache clang++"
ccache -s
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
-DENABLE_QT_TRANSLATION=ON \
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DUSE_DISCORD_PRESENCE=ON \
-DENABLE_FFMPEG_AUDIO_DECODER=ON \
-DENABLE_FFMPEG_VIDEO_DUMPER=ON \
-GNinja
ninja
ccache -s
ctest -VV -C Release

View File

@ -1,23 +0,0 @@
#!/bin/sh -ex
brew update
brew unlink python@2 || true
rm '/usr/local/bin/2to3' || true
brew install qt5 p7zip ccache ninja || true
pip3 install macpack
export SDL_VER=2.0.16
export FFMPEG_VER=4.4
mkdir tmp
cd tmp/
# install SDL
wget https://github.com/SachinVin/ext-macos-bin/raw/main/sdl2/sdl-${SDL_VER}.7z
7z x sdl-${SDL_VER}.7z
cp -rv $(pwd)/sdl-${SDL_VER}/* /
# install FFMPEG
wget https://github.com/SachinVin/ext-macos-bin/raw/main/ffmpeg/ffmpeg-${FFMPEG_VER}.7z
7z x ffmpeg-${FFMPEG_VER}.7z
cp -rv $(pwd)/ffmpeg-${FFMPEG_VER}/* /

View File

@ -1,33 +0,0 @@
#!/bin/bash -ex
. .ci/common/pre-upload.sh
REV_NAME="citra-osx-${GITDATE}-${GITREV}"
ARCHIVE_NAME="${REV_NAME}.tar.gz"
COMPRESSION_FLAGS="-czvf"
mkdir "$REV_NAME"
cp build/bin/Release/citra "$REV_NAME"
cp -r build/bin/Release/citra-qt.app "$REV_NAME"
cp build/bin/Release/citra-room "$REV_NAME"
# move libs into folder for deployment
macpack "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt" -d "../Frameworks"
# move qt frameworks into app bundle for deployment
$(brew --prefix)/opt/qt5/bin/macdeployqt "${REV_NAME}/citra-qt.app" -executable="${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt"
# move libs into folder for deployment
macpack "${REV_NAME}/citra" -d "libs"
# workaround for libc++
install_name_tool -change @loader_path/../Frameworks/libc++.1.0.dylib /usr/lib/libc++.1.dylib "${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt"
install_name_tool -change @loader_path/libs/libc++.1.0.dylib /usr/lib/libc++.1.dylib "${REV_NAME}/citra"
# Make the launching script executable
chmod +x ${REV_NAME}/citra-qt.app/Contents/MacOS/citra-qt
# Verify loader instructions
find "$REV_NAME" -type f -exec otool -L {} \;
. .ci/common/post-upload.sh

80
.ci/pack.sh Executable file
View File

@ -0,0 +1,80 @@
#!/bin/bash -ex
# Determine the full revision name.
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
REV_NAME="citra-$OS-$TARGET-$GITDATE-$GITREV"
# Determine the name of the release being built.
if [[ "$GITHUB_REF_NAME" =~ ^canary- ]] || [[ "$GITHUB_REF_NAME" =~ ^nightly- ]]; then
RELEASE_NAME=$(echo $GITHUB_REF_NAME | cut -d- -f1)
else
RELEASE_NAME=head
fi
# Archive and upload the artifacts.
mkdir artifacts
function pack_artifacts() {
ARTIFACTS_PATH="$1"
# Set up root directory for archive.
mkdir "$REV_NAME"
if [ -f "$ARTIFACTS_PATH" ]; then
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
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
powershell Compress-Archive "$REV_NAME" "$ARCHIVE_FULL_NAME"
elif [ "$OS" = "android" ]; then
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.zip"
zip -r "$ARCHIVE_FULL_NAME" "$REV_NAME"
else
ARCHIVE_FULL_NAME="$ARCHIVE_NAME.tar.gz"
tar czvf "$ARCHIVE_FULL_NAME" "$REV_NAME"
fi
mv "$ARCHIVE_FULL_NAME" artifacts/
if [ -z "$SKIP_7Z" ]; then
# Create .7z
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.
rm -rf "$RELEASE_NAME"
else
# Clean up created rev artifacts directory.
rm -rf "$REV_NAME"
fi
}
if [ -n "$UNPACKED" ]; then
# Copy the artifacts to be uploaded unpacked.
for ARTIFACT in build/bundle/*; do
FILENAME=$(basename "$ARTIFACT")
EXTENSION="${FILENAME##*.}"
mv "$ARTIFACT" "artifacts/$REV_NAME.$EXTENSION"
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

20
.ci/source.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash -ex
GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`"
GITREV="`git show -s --format='%h'`"
REV_NAME="citra-unified-source-${GITDATE}-${GITREV}"
COMPAT_LIST='dist/compatibility_list/compatibility_list.json'
mkdir artifacts
pip3 install git-archive-all
wget -q https://api.citra-emu.org/gamedb -O "${COMPAT_LIST}"
git describe --abbrev=0 --always HEAD > GIT-COMMIT
git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG
git archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar"
cd artifacts/
xz -T0 -9 "${REV_NAME}.tar"
sha256sum "${REV_NAME}.tar.xz" > "${REV_NAME}.tar.xz.sha256sum"
cd ..

14
.ci/transifex.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash -ex
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
cmake --version
gcc -v
tx --version
mkdir build && cd build
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF
make translation
cd ..
cd dist/languages
tx push -s

View File

@ -1,3 +0,0 @@
#!/bin/bash -e
docker run -e TRANSIFEX_API_TOKEN="${TRANSIFEX_API_TOKEN}" -v "$(pwd)":/citra citraemu/build-environments:linux-transifex /bin/sh -e /citra/.travis/transifex/docker.sh

View File

@ -1,39 +0,0 @@
#!/bin/bash -e
# Setup RC file for tx
cat << EOF > ~/.transifexrc
[https://www.transifex.com]
hostname = https://www.transifex.com
username = api
password = $TRANSIFEX_API_TOKEN
EOF
set -x
cat << 'EOF' > /usr/bin/tx
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import re
import sys
from txclib.cmdline import main
if __name__ == '__main__':
sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
sys.exit(main())
EOF
echo -e "\e[1m\e[33mBuild tools information:\e[0m"
cmake --version
gcc -v
tx --version
mkdir build && cd build
cmake .. -DENABLE_QT_TRANSLATION=ON -DGENERATE_QT_TRANSLATION=ON -DCMAKE_BUILD_TYPE=Release -DENABLE_SDL2=OFF
make translation
cd ..
cd dist/languages
tx push -s

View File

@ -1,10 +0,0 @@
#!/bin/sh -ex
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -G Ninja -DCMAKE_TOOLCHAIN_FILE="$(pwd)/../CMakeModules/MSVCCache.cmake" -DUSE_CCACHE=ON -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON -DUSE_DISCORD_PRESENCE=ON -DENABLE_MF=ON -DENABLE_FFMPEG_VIDEO_DUMPER=ON
ninja
# show the caching efficiency
buildcache -s
ctest -VV -C Release || echo "::error ::Test error occurred on Windows MSVC build"

View File

@ -1,10 +0,0 @@
#!/bin/sh -ex
BUILDCACHE_VERSION="0.22.3"
choco install wget ninja
# Install buildcache
wget "https://github.com/mbitsnbites/buildcache/releases/download/v${BUILDCACHE_VERSION}/buildcache-win-mingw.zip"
7z x 'buildcache-win-mingw.zip'
mv ./buildcache/bin/buildcache.exe "/c/ProgramData/chocolatey/bin"
rm -rf ./buildcache/

17
.ci/windows.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/sh -ex
mkdir build && cd build
cmake .. -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DENABLE_QT_TRANSLATION=ON \
-DCITRA_ENABLE_COMPATIBILITY_REPORTING=ON \
-DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON \
-DUSE_DISCORD_PRESENCE=ON
ninja
ninja bundle
ccache -s -v
ctest -VV -C Release || echo "::error ::Test error occurred on Windows build"

View File

@ -0,0 +1,10 @@
name: New Issue (Developers Only)
description: A blank issue template for developers only. If you are not a developer, do not use this issue template. Your issue WILL BE CLOSED if you do not use the appropriate issue template.
body:
- type: markdown
attributes:
value: |
**If you are not a developer, do not use this issue template. Your issue WILL BE CLOSED if you do not use the appropriate issue template.**
- type: textarea
attributes:
label: "Issue"

View File

@ -1,35 +0,0 @@
---
name: Bug Report / Feature Request
about: Tech support does not belong here. You should only file an issue here if you think you have experienced an actual bug with Citra or you are requesting a feature you believe would make Citra better.
title: ''
labels: ''
assignees: ''
---
<!---
Please read the FAQ:
https://citra-emu.org/wiki/faq/
THIS IS NOT A SUPPORT FORUM, FOR SUPPORT GO TO:
https://community.citra-emu.org/
If the FAQ does not answer your question, please go to:
https://community.citra-emu.org/
====================================================
When submitting an issue, please check the following:
- You have read the above.
- You have provided the version (commit hash) of Citra you are using.
- You have provided sufficient detail for the issue to be reproduced.
- You have provided system specs (if relevant).
- Please also provide:
- For any issues, a log file
- For crashes, a backtrace.
- For graphical issues, comparison screenshots with real hardware.
- For emulation inaccuracies, a test-case (if able).
--->

64
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,64 @@
name: Bug Report
description: File a bug report
body:
- type: markdown
attributes:
value: Tech support does not belong here. You should only file an issue here if you think you have experienced an actual bug with Citra.
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: input
attributes:
label: Affected Build(s)
description: List the affected build(s) that this issue applies to.
placeholder: Nightly 1234 / Canary 1234
validations:
required: true
- type: textarea
id: issue-desc
attributes:
label: Description of Issue
description: A brief description of the issue encountered along with any images and/or videos.
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected Behavior
description: A brief description of how it is expected to work along with any images and/or videos.
validations:
required: true
- type: textarea
id: reproduction-steps
attributes:
label: Reproduction Steps
description: A brief explanation of how to reproduce this issue. If possible, provide a save file to aid in reproducing the issue.
validations:
required: true
- type: textarea
id: log
attributes:
label: Log File
description: A log file will help our developers to better diagnose and fix the issue. Instructions can be found [here](https://community.citra-emu.org/t/how-to-upload-the-log-file/296).
validations:
required: true
- type: textarea
id: system-config
attributes:
label: System Configuration
placeholder: |
CPU: Intel i5-10400 / AMD Ryzen 5 3600
GPU/Driver: NVIDIA GeForce GTX 1060 (Driver 512.95)
RAM: 16GB DDR4-3200
OS: Windows 11 22H2 (Build 22621.819)
value: |
CPU:
GPU/Driver:
RAM:
OS:
validations:
required: true

View File

@ -6,6 +6,3 @@ contact_links:
- name: Community forums
url: https://community.citra-emu.org
about: This is an alternative place for tech support, however helpers there are not as active.
- name: Citra Android
url: https://github.com/citra-emu/citra-android
about: If you need tech support on Citra Android, you should use either of the above two options. If you want to file an issue, you should go to the Android repo linked here.

View File

@ -0,0 +1,28 @@
name: Feature Request
description: File a feature request
labels: "request"
body:
- type: markdown
attributes:
value: Tech support does not belong here. You should only file an issue here if you are requesting a feature you believe would make Citra better.
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the feature you are requesting.
options:
- label: I have searched the existing issues
required: true
- type: textarea
id: what-feature
attributes:
label: What feature are you suggesting?
description: A brief description of the requested feature.
validations:
required: true
- type: textarea
id: why-feature
attributes:
label: Why would this feature be useful?
description: A brief description of why this feature would make Citra better.
validations:
required: true

View File

@ -1,212 +0,0 @@
// Note: This is a GitHub Actions script
// It is not meant to be executed directly on your machine without modifications
const fs = require("fs");
// how far back in time should we consider the changes are "recent"? (default: 24 hours)
const DETECTION_TIME_FRAME = (parseInt(process.env.DETECTION_TIME_FRAME)) || (24 * 3600 * 1000);
async function checkBaseChanges(github, context) {
// query the commit date of the latest commit on this branch
const query = `query($owner:String!, $name:String!, $ref:String!) {
repository(name:$name, owner:$owner) {
ref(qualifiedName:$ref) {
target {
... on Commit { id pushedDate oid }
}
}
}
}`;
const variables = {
owner: context.repo.owner,
name: context.repo.repo,
ref: 'refs/heads/master',
};
const result = await github.graphql(query, variables);
const pushedAt = result.repository.ref.target.pushedDate;
console.log(`Last commit pushed at ${pushedAt}.`);
const delta = new Date() - new Date(pushedAt);
if (delta <= DETECTION_TIME_FRAME) {
console.info('New changes detected, triggering a new build.');
return true;
}
console.info('No new changes detected.');
return false;
}
async function checkCanaryChanges(github, context) {
if (checkBaseChanges(github, context)) return true;
const query = `query($owner:String!, $name:String!, $label:String!) {
repository(name:$name, owner:$owner) {
pullRequests(labels: [$label], states: OPEN, first: 100) {
nodes { number headRepository { pushedAt } }
}
}
}`;
const variables = {
owner: context.repo.owner,
name: context.repo.repo,
label: "canary-merge",
};
const result = await github.graphql(query, variables);
const pulls = result.repository.pullRequests.nodes;
for (let i = 0; i < pulls.length; i++) {
let pull = pulls[i];
if (new Date() - new Date(pull.headRepository.pushedAt) <= DETECTION_TIME_FRAME) {
console.info(`${pull.number} updated at ${pull.headRepository.pushedAt}`);
return true;
}
}
console.info("No changes detected in any tagged pull requests.");
return false;
}
async function tagAndPush(github, owner, repo, execa, commit=false) {
let altToken = process.env.ALT_GITHUB_TOKEN;
if (!altToken) {
throw `Please set ALT_GITHUB_TOKEN environment variable. This token should have write access to ${owner}/${repo}.`;
}
const query = `query ($owner:String!, $name:String!) {
repository(name:$name, owner:$owner) {
refs(refPrefix: "refs/tags/", orderBy: {field: TAG_COMMIT_DATE, direction: DESC}, first: 10) {
nodes { name }
}
}
}`;
const variables = {
owner: owner,
name: repo,
};
const tags = await github.graphql(query, variables);
let lastTag = tags.repository.refs.nodes[0].name;
let tagNumber = /\w+-(\d+)/.exec(lastTag)[1] | 0;
let channel = repo.split('-')[1];
let newTag = `${channel}-${tagNumber + 1}`;
console.log(`New tag: ${newTag}`);
if (commit) {
let channelName = channel[0].toUpperCase() + channel.slice(1);
console.info(`Committing pending commit as ${channelName} #${tagNumber + 1}`);
await execa("git", ['commit', '-m', `${channelName} #${tagNumber + 1}`]);
}
console.info('Pushing tags to GitHub ...');
await execa("git", ['tag', newTag]);
await execa("git", ['remote', 'add', 'target', `https://${altToken}@github.com/${owner}/${repo}.git`]);
await execa("git", ['push', 'target', 'master', '-f']);
await execa("git", ['push', 'target', 'master', '-f', '--tags']);
console.info('Successfully pushed new changes.');
}
async function generateReadme(pulls, context, mergeResults, execa) {
let baseUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/`;
let output =
"| Pull Request | Commit | Title | Author | Merged? |\n|----|----|----|----|----|\n";
for (let pull of pulls) {
let pr = pull.number;
let result = mergeResults[pr];
output += `| [${pr}](${baseUrl}/pull/${pr}) | [\`${result.rev || "N/A"}\`](${baseUrl}/pull/${pr}/files) | ${pull.title} | [${pull.author.login}](https://github.com/${pull.author.login}/) | ${result.success ? "Yes" : "No"} |\n`;
}
output +=
"\n\nEnd of merge log. You can find the original README.md below the break.\n\n-----\n\n";
output += fs.readFileSync("./README.md");
fs.writeFileSync("./README.md", output);
await execa("git", ["add", "README.md"]);
}
async function fetchPullRequests(pulls, repoUrl, execa) {
console.log("::group::Fetch pull requests");
for (let pull of pulls) {
let pr = pull.number;
console.info(`Fetching PR ${pr} ...`);
await execa("git", [
"fetch",
"-f",
"--no-recurse-submodules",
repoUrl,
`pull/${pr}/head:pr-${pr}`,
]);
}
console.log("::endgroup::");
}
async function mergePullRequests(pulls, execa) {
let mergeResults = {};
console.log("::group::Merge pull requests");
await execa("git", ["config", "--global", "user.name", "citrabot"]);
await execa("git", [
"config",
"--global",
"user.email",
"citra\x40citra-emu\x2eorg", // prevent email harvesters from scraping the address
]);
let hasFailed = false;
for (let pull of pulls) {
let pr = pull.number;
console.info(`Merging PR ${pr} ...`);
try {
const process1 = execa("git", [
"merge",
"--squash",
"--no-edit",
`pr-${pr}`,
]);
process1.stdout.pipe(process.stdout);
await process1;
const process2 = execa("git", ["commit", "-m", `Merge PR ${pr}`]);
process2.stdout.pipe(process.stdout);
await process2;
const process3 = await execa("git", ["rev-parse", "--short", `pr-${pr}`]);
mergeResults[pr] = {
success: true,
rev: process3.stdout,
};
} catch (err) {
console.log(
`::error title=#${pr} not merged::Failed to merge pull request: ${pr}: ${err}`
);
mergeResults[pr] = { success: false };
hasFailed = true;
await execa("git", ["reset", "--hard"]);
}
}
console.log("::endgroup::");
if (hasFailed) {
throw 'There are merge failures. Aborting!';
}
return mergeResults;
}
async function mergebot(github, context, execa) {
const query = `query ($owner:String!, $name:String!, $label:String!) {
repository(name:$name, owner:$owner) {
pullRequests(labels: [$label], states: OPEN, first: 100) {
nodes {
number title author { login }
}
}
}
}`;
const variables = {
owner: context.repo.owner,
name: context.repo.repo,
label: "canary-merge",
};
const result = await github.graphql(query, variables);
const pulls = result.repository.pullRequests.nodes;
let displayList = [];
for (let i = 0; i < pulls.length; i++) {
let pull = pulls[i];
displayList.push({ PR: pull.number, Title: pull.title });
}
console.info("The following pull requests will be merged:");
console.table(displayList);
await fetchPullRequests(pulls, "https://github.com/citra-emu/citra", execa);
const mergeResults = await mergePullRequests(pulls, execa);
await generateReadme(pulls, context, mergeResults, execa);
await tagAndPush(github, context.repo.owner, `${context.repo.repo}-canary`, execa, true);
}
module.exports.mergebot = mergebot;
module.exports.checkCanaryChanges = checkCanaryChanges;
module.exports.tagAndPush = tagAndPush;
module.exports.checkBaseChanges = checkBaseChanges;

View File

@ -1,145 +0,0 @@
name: citra-ci
on:
push:
branches: [ "*" ]
tags: [ "*" ]
pull_request:
branches: [ master ]
jobs:
clang-format:
runs-on: ubuntu-latest
container: citraemu/build-environments:linux-clang-format
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Build
env:
COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}
run: ./.ci/linux-clang-format/docker.sh
build:
runs-on: ubuntu-latest
strategy:
matrix:
image: ["linux-fresh", "linux-frozen", "linux-mingw"]
container: citraemu/build-environments:${{ matrix.image }}
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Set up cache
uses: actions/cache@v2
with:
path: ~/.ccache
key: ${{ runner.os }}-${{ matrix.image }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.image }}-
- name: Query tag name
uses: little-core-labs/get-git-tag@v3.0.2
id: tagName
- name: Build
run: ./.ci/${{ matrix.image }}/docker.sh
env:
ENABLE_COMPATIBILITY_REPORTING: "ON"
- name: Pack
run: ./.ci/${{ matrix.image }}/upload.sh
if: ${{ matrix.image != 'linux-frozen' }}
env:
NAME: ${{ matrix.image }}
- name: Upload
uses: actions/upload-artifact@v2
if: ${{ matrix.image != 'linux-frozen' }}
with:
name: ${{ matrix.image }}
path: artifacts/
macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Set up cache
uses: actions/cache@v2
with:
path: ~/Library/Caches/ccache
key: ${{ runner.os }}-macos-${{ github.sha }}
restore-keys: |
${{ runner.os }}-macos-
- name: Query tag name
uses: little-core-labs/get-git-tag@v3.0.2
id: tagName
- name: Install dependencies
run: ./.ci/macos/deps.sh
- name: Build
run: ./.ci/macos/build.sh
env:
MACOSX_DEPLOYMENT_TARGET: "10.13"
ENABLE_COMPATIBILITY_REPORTING: "ON"
- name: Pack
run: ./.ci/macos/upload.sh
- name: Upload
uses: actions/upload-artifact@v2
with:
name: macos
path: artifacts/
windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Set up cache
uses: actions/cache@v2
with:
path: ~/.buildcache
key: ${{ runner.os }}-win-${{ github.sha }}
restore-keys: |
${{ runner.os }}-win-
- name: Install dependencies
run: ./.ci/windows-msvc/deps.sh
shell: bash
- name: Set up MSVC
uses: ilammy/msvc-dev-cmd@v1
- name: Build
run: ./.ci/windows-msvc/build.sh
shell: bash
env:
ENABLE_COMPATIBILITY_REPORTING: "ON"
transifex:
runs-on: ubuntu-latest
container: citraemu/build-environments:linux-transifex
if: ${{ github.repository == 'citra-emu/citra' && !github.head_ref }}
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Update Translation
run: ./.ci/transifex/docker.sh
env:
TRANSIFEX_API_TOKEN: ${{ secrets.TRANSIFEX_API_TOKEN }}
release:
runs-on: ubuntu-latest
needs: [build, macos]
if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps:
- uses: actions/download-artifact@v2
- name: Query tag name
uses: little-core-labs/get-git-tag@v3.0.2
id: tagName
- name: Create release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ steps.tagName.outputs.tag }}
release_name: ${{ steps.tagName.outputs.tag }}
draft: false
prerelease: false
- name: Upload artifacts
uses: alexellis/upload-assets@0.2.3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
asset_paths: '["./**/*.tar.*","./**/*.7z","./**/*.zip"]'

View File

@ -1,100 +0,0 @@
name: citra-publish
on:
schedule:
- cron: '7 0 * * *'
workflow_dispatch:
inputs:
nightly:
description: 'Whether to trigger a nightly build (true/false/auto)'
required: false
default: 'true'
canary:
description: 'Whether to trigger a canary build (true/false/auto)'
required: false
default: 'true'
jobs:
nightly:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.nightly != 'false' && github.repository == 'citra-emu/citra' }}
steps:
# this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v2
name: Pre-checkout
with:
submodules: false
- uses: actions/github-script@v5
id: check-changes
name: 'Check for new changes'
env:
# 24 hours
DETECTION_TIME_FRAME: 86400000
with:
result-encoding: string
script: |
if (context.payload.inputs && context.payload.inputs.nightly === 'true') return true;
const checkBaseChanges = require('./.github/workflows/ci-merge.js').checkBaseChanges;
return checkBaseChanges(github, context);
- run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v2
name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }}
with:
path: 'citra-merge'
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v5
name: 'Update and tag new commits'
if: ${{ steps.check-changes.outputs.result == 'true' }}
env:
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
with:
script: |
const execa = require("execa");
const tagAndPush = require('./.github/workflows/ci-merge.js').tagAndPush;
process.chdir('${{ github.workspace }}/citra-merge');
tagAndPush(github, context.repo.owner, `${context.repo.repo}-nightly`, execa);
canary:
runs-on: ubuntu-latest
if: ${{ github.event.inputs.canary != 'false' && github.repository == 'citra-emu/citra' }}
steps:
# this checkout is required to make sure the GitHub Actions scripts are available
- uses: actions/checkout@v2
name: Pre-checkout
with:
submodules: false
- uses: actions/github-script@v5
id: check-changes
name: 'Check for new changes'
env:
# 24 hours
DETECTION_TIME_FRAME: 86400000
with:
script: |
if (context.payload.inputs && context.payload.inputs.canary === 'true') return true;
const checkCanaryChanges = require('./.github/workflows/ci-merge.js').checkCanaryChanges;
return checkCanaryChanges(github, context);
- run: npm install execa@5
if: ${{ steps.check-changes.outputs.result == 'true' }}
- uses: actions/checkout@v2
name: Checkout
if: ${{ steps.check-changes.outputs.result == 'true' }}
with:
path: 'citra-merge'
fetch-depth: 0
submodules: true
token: ${{ secrets.ALT_GITHUB_TOKEN }}
- uses: actions/github-script@v5
name: 'Check and merge canary changes'
if: ${{ steps.check-changes.outputs.result == 'true' }}
env:
ALT_GITHUB_TOKEN: ${{ secrets.ALT_GITHUB_TOKEN }}
with:
script: |
const execa = require("execa");
const mergebot = require('./.github/workflows/ci-merge.js').mergebot;
process.chdir('${{ github.workspace }}/citra-merge');
mergebot(github, context, execa);

11
.gitignore vendored
View File

@ -1,16 +1,22 @@
# Build directory
[Bb]uild/
[Bb]uild*/
doc-build/
build-*/
# Generated source files
src/common/scm_rev.cpp
.travis.descriptor.json
# Project/editor files
*.swp
*.kdev4
.idea/
.vs/
.vscode/
.cache/
.kdev4/
cmake-build-debug/
cmake-build-release/
CMakeLists.txt.user*
*.dll
*.dll.manifest
@ -44,6 +50,7 @@ Thumbs.db
repo/
# GitHub Actions generated files
.ccache/
node_modules/
# RA artifacts
@ -54,3 +61,5 @@ src/video_core/shaders/
# Android
obj/
libs/
VULKAN_SDK/

63
.gitmodules vendored
View File

@ -1,24 +1,21 @@
[submodule "boost"]
path = externals/boost
url = https://github.com/libretro-fork/ext-boost.git
url = https://github.com/citra-emu/ext-boost.git
[submodule "nihstro"]
path = externals/nihstro
url = https://github.com/libretro-fork/nihstro.git
url = https://github.com/neobrain/nihstro.git
[submodule "soundtouch"]
path = externals/soundtouch
url = https://github.com/rtiangha/ext-soundtouch.git
[submodule "catch"]
path = externals/catch
url = https://github.com/philsquared/Catch.git
url = https://codeberg.org/soundtouch/soundtouch.git
[submodule "catch2"]
path = externals/catch2
url = https://github.com/catchorg/Catch2
[submodule "dynarmic"]
path = externals/dynarmic
url = https://github.com/rtiangha/dynarmic-old.git
url = https://github.com/merryhime/dynarmic.git
[submodule "xbyak"]
path = externals/xbyak
url = https://github.com/herumi/xbyak.git
[submodule "cryptopp"]
path = externals/cryptopp/cryptopp
url = https://github.com/weidai11/cryptopp.git
[submodule "fmt"]
path = externals/fmt
url = https://github.com/fmtlib/fmt.git
@ -36,10 +33,10 @@
url = https://github.com/libusb/libusb.git
[submodule "cubeb"]
path = externals/cubeb
url = https://github.com/kinetiknz/cubeb.git
url = https://github.com/mozilla/cubeb
[submodule "discord-rpc"]
path = externals/discord-rpc
url = https://github.com/discord/discord-rpc.git
url = https://github.com/yuzu-emu/discord-rpc.git
[submodule "cpp-jwt"]
path = externals/cpp-jwt
url = https://github.com/arun11299/cpp-jwt.git
@ -55,6 +52,42 @@
[submodule "libyuv"]
path = externals/libyuv
url = https://github.com/lemenkov/libyuv.git
[submodule "externals/ffmpeg"]
path = externals/ffmpeg
url = https://github.com/FFmpeg/FFmpeg
[submodule "sdl2"]
path = externals/sdl2/SDL
url = https://github.com/libsdl-org/SDL
[submodule "cryptopp-cmake"]
path = externals/cryptopp-cmake
url = https://github.com/abdes/cryptopp-cmake.git
[submodule "cryptopp"]
path = externals/cryptopp
url = https://github.com/weidai11/cryptopp.git
[submodule "dds-ktx"]
path = externals/dds-ktx
url = https://github.com/septag/dds-ktx
[submodule "openal-soft"]
path = externals/openal-soft
url = https://github.com/kcat/openal-soft
[submodule "glslang"]
path = externals/glslang
url = https://github.com/KhronosGroup/glslang
[submodule "vma"]
path = externals/vma
url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
[submodule "vulkan-headers"]
path = externals/vulkan-headers
url = https://github.com/KhronosGroup/Vulkan-Headers
[submodule "sirit"]
path = externals/sirit
url = https://github.com/yuzu-emu/sirit
[submodule "faad2"]
path = externals/faad2/faad2
url = https://github.com/knik0/faad2
[submodule "library-headers"]
path = externals/library-headers
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

View File

@ -1,13 +0,0 @@
path_classifiers:
library: "externals"
extraction:
cpp:
prepare:
packages:
- "libsdl2-dev"
- "qtmultimedia5-dev"
- "clang-format-6.0"
- "libtbb-dev"
- "libjack-jackd2-dev"
- "doxygen"
- "graphviz"

View File

@ -1,9 +1,15 @@
# CMake 3.8 required for 17 to be a valid value for CXX_STANDARD
cmake_minimum_required(VERSION 3.8)
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.15)
# Don't override the warning flags in MSVC:
cmake_policy(SET CMP0092 NEW)
endif ()
# CMake 3.12 required for 20 to be a valid value for CXX_STANDARD
cmake_minimum_required(VERSION 3.15)
# Don't override the warning flags in MSVC:
cmake_policy(SET CMP0092 NEW)
# Enforce new LTO setting
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}/externals/cmake-modules")
include(DownloadExternals)
@ -11,39 +17,92 @@ include(CMakeDependentOption)
project(citra LANGUAGES C CXX ASM)
# Set bundled sdl2/qt as dependent options.
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
option(ENABLE_LIBRETRO "Enable the LibRetro frontend" ON)
option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_QT;MSVC" OFF)
option(ENABLE_LIBRETRO "Enable the LibRetro frontend" OFF)
option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
option(ENABLE_CUBEB "Enables the cubeb audio backend" OFF)
option(ENABLE_FFMPEG_AUDIO_DECODER "Enable FFmpeg audio (AAC) decoder" OFF)
option(ENABLE_FFMPEG_VIDEO_DUMPER "Enable FFmpeg video dumper" OFF)
if (ENABLE_FFMPEG_AUDIO_DECODER OR ENABLE_FFMPEG_VIDEO_DUMPER)
set(ENABLE_FFMPEG ON)
# Some submodules like to pick their own default build type if not specified.
# Make sure we default to Release build type always, unless the generator has custom types.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build." FORCE)
endif()
CMAKE_DEPENDENT_OPTION(CITRA_USE_BUNDLED_FFMPEG "Download bundled FFmpeg binaries" ON "ENABLE_FFMPEG;MSVC" OFF)
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()
if (CMAKE_BUILD_TYPE STREQUAL Debug)
set(IS_DEBUG_BUILD ON)
set(IS_RELEASE_BUILD OFF)
else()
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()
option(ENABLE_SDL2 "Enable using SDL2" OFF)
CMAKE_DEPENDENT_OPTION(ENABLE_SDL2_FRONTEND "Enable the SDL2 frontend" ON "ENABLE_SDL2;NOT ANDROID AND NOT IOS" OFF)
option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OFF)
# Set bundled qt as dependent options.
option(ENABLE_QT "Enable the Qt frontend" ON)
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
CMAKE_DEPENDENT_OPTION(ENABLE_QT_UPDATER "Enable built-in updater for the Qt frontend" ON "NOT IOS" OFF)
CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "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_SCRIPTING "Enable RPC server for scripting" ON)
# TODO: cubeb currently causes issues on macOS, see: https://github.com/mozilla/cubeb/issues/771
CMAKE_DEPENDENT_OPTION(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT APPLE" OFF)
option(ENABLE_OPENAL "Enables the OpenAL audio backend" ON)
CMAKE_DEPENDENT_OPTION(ENABLE_LIBUSB "Enable libusb for GameCube Adapter support" ON "NOT IOS" 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(CITRA_ENABLE_BUNDLE_TARGET "Enable the distribution bundling target." ON "NOT ANDROID AND NOT IOS" OFF)
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF)
# Compile options
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(CITRA_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
option(CITRA_WARNINGS_AS_ERRORS "Enable warnings as errors" ON)
option(USE_SYSTEM_BOOST "Use the system Boost libs (instead of the bundled ones)" OFF)
include(CitraHandleSystemLibs)
CMAKE_DEPENDENT_OPTION(ENABLE_FDK "Use FDK AAC decoder" OFF "NOT ENABLE_FFMPEG_AUDIO_DECODER;NOT ENABLE_MF" OFF)
if (CITRA_USE_PRECOMPILED_HEADERS)
message(STATUS "Using Precompiled Headers.")
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()
if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
message(STATUS "Copying pre-commit hook")
@ -51,6 +110,30 @@ if(NOT EXISTS ${PROJECT_SOURCE_DIR}/.git/hooks/pre-commit)
DESTINATION ${PROJECT_SOURCE_DIR}/.git/hooks)
endif()
# Use ccache for android if available
# =======================================================================
if (NOT $ENV{NDK_CCACHE} EQUAL "")
set(CCACHE_EXE $ENV{NDK_CCACHE})
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_EXE})
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_EXE})
endif()
# Check for LTO support
# =======================================================================
if (ENABLE_LTO)
include(CheckIPOSupported)
check_ipo_supported(RESULT supported OUTPUT error_msg)
if (supported)
message(STATUS "LTO enabled")
else()
message(STATUS "LTO enabled but is unavailable, disabling: ${error_msg}")
set(ENABLE_LTO OFF)
endif()
else()
message(STATUS "LTO disabled")
endif()
# Sanity check : Check that all submodules are present
# =======================================================================
@ -65,7 +148,10 @@ function(check_submodules_present)
endif()
endforeach()
endfunction()
check_submodules_present()
if (EXISTS "${PROJECT_SOURCE_DIR}/.git/objects")
# only check submodules when source is obtained via Git
check_submodules_present()
endif()
configure_file(${PROJECT_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
${PROJECT_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
@ -98,29 +184,27 @@ function(detect_architecture symbol arch)
# CMake's crazy scope rules will keep it defined
if (ARCHITECTURE_${arch})
set(ARCHITECTURE "${arch}" PARENT_SCOPE)
set(ARCHITECTURE_${arch} 1 PARENT_SCOPE)
add_definitions(-DARCHITECTURE_${arch}=1)
endif()
endif()
endfunction()
if (NOT ENABLE_GENERIC)
if (MSVC)
if (CMAKE_OSX_ARCHITECTURES)
set(ARCHITECTURE "${CMAKE_OSX_ARCHITECTURES}")
elseif (MSVC)
detect_architecture("_M_AMD64" x86_64)
detect_architecture("_M_IX86" x86)
detect_architecture("_M_ARM" ARM)
detect_architecture("_M_ARM64" ARM64)
detect_architecture("_M_ARM" arm)
detect_architecture("_M_ARM64" arm64)
else()
detect_architecture("__x86_64__" x86_64)
detect_architecture("__i386__" x86)
detect_architecture("__arm__" ARM)
detect_architecture("__aarch64__" ARM64)
detect_architecture("__arm__" arm)
detect_architecture("__aarch64__" arm64)
endif()
endif()
if (NOT DEFINED ARCHITECTURE)
set(ARCHITECTURE "GENERIC")
set(ARCHITECTURE_GENERIC 1)
add_definitions(-DARCHITECTURE_GENERIC=1)
endif()
message(STATUS "Target architecture: ${ARCHITECTURE}")
@ -128,9 +212,17 @@ message(STATUS "Target architecture: ${ARCHITECTURE}")
# Configure C++ standard
# ===========================
set(CMAKE_CXX_STANDARD 17)
# boost asio's concept usage doesn't play nicely with some compilers yet.
add_definitions(-DBOOST_ASIO_DISABLE_CONCEPTS)
# boost can have issues compiling with C++17 and up on newer versions of Clang.
add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE)
set(CMAKE_CXX_STANDARD 20)
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(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin/$<CONFIG>)
@ -215,123 +307,48 @@ add_definitions(-DEMU_ARCH_BITS=${EMU_ARCH_BITS})
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
if (ENABLE_SDL2)
if (CITRA_USE_BUNDLED_SDL2)
# Detect toolchain and platform
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(SDL2_VER "SDL2-2.0.16")
else()
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.")
endif()
if (DEFINED SDL2_VER)
download_bundled_external("sdl2/" ${SDL2_VER} SDL2_PREFIX)
endif()
set(SDL2_FOUND YES)
set(SDL2_INCLUDE_DIR "${SDL2_PREFIX}/include" CACHE PATH "Path to SDL2 headers")
set(SDL2_LIBRARY "${SDL2_PREFIX}/lib/x64/SDL2.lib" CACHE PATH "Path to SDL2 library")
set(SDL2_DLL_DIR "${SDL2_PREFIX}/lib/x64/" CACHE PATH "Path to SDL2.dll")
else()
find_package(SDL2 REQUIRED)
endif()
if (SDL2_FOUND)
# TODO(yuriks): Make FindSDL2.cmake export an IMPORTED library instead
add_library(SDL2 INTERFACE)
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
endif()
else()
set(SDL2_FOUND NO)
endif()
if (ENABLE_QT)
if (CITRA_USE_BUNDLED_QT)
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(QT_VER qt-5.10.0-msvc2017_64)
else()
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
endif()
if (DEFINED QT_VER)
download_bundled_external("qt/" ${QT_VER} QT_PREFIX)
endif()
set(QT_PREFIX_HINT HINTS "${QT_PREFIX}")
else()
# Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so
# make sure to not pass anything if we don't have one.
set(QT_PREFIX_HINT)
if (NOT USE_SYSTEM_QT)
download_qt(6.6.0)
endif()
find_package(Qt5 REQUIRED COMPONENTS Widgets Multimedia ${QT_PREFIX_HINT})
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
if (UNIX AND NOT APPLE)
find_package(Qt6 REQUIRED COMPONENTS DBus)
endif()
if (ENABLE_QT_TRANSLATION)
find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT})
find_package(Qt6 REQUIRED COMPONENTS LinguistTools)
endif()
endif()
# Ensure libusb is properly configured (based on dolphin libusb include)
if(NOT APPLE)
include(FindPkgConfig)
find_package(LibUSB)
endif()
if (NOT LIBUSB_FOUND)
add_subdirectory(externals/libusb)
set(LIBUSB_INCLUDE_DIR "")
set(LIBUSB_LIBRARIES usb)
endif()
# Use system tsl::robin_map if available (otherwise we fallback to version bundled with dynarmic)
find_package(tsl-robin-map QUIET)
if (ENABLE_FFMPEG)
if (CITRA_USE_BUNDLED_FFMPEG)
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
set(FFmpeg_VER "ffmpeg-4.1-win64")
else()
message(FATAL_ERROR "No bundled FFmpeg binaries for your toolchain. Disable CITRA_USE_BUNDLED_FFMPEG and provide your own.")
endif()
if (DEFINED FFmpeg_VER)
download_bundled_external("ffmpeg/" ${FFmpeg_VER} FFmpeg_PREFIX)
set(FFMPEG_DIR "${FFmpeg_PREFIX}")
endif()
endif()
if (ENABLE_FFMPEG_VIDEO_DUMPER)
find_package(FFmpeg REQUIRED COMPONENTS avcodec avformat avutil swscale swresample)
else()
find_package(FFmpeg REQUIRED COMPONENTS avcodec)
endif()
if ("${FFmpeg_avcodec_VERSION}" VERSION_LESS "57.48.101")
message(FATAL_ERROR "Found version for libavcodec is too low. The required version is at least 57.48.101 (included in FFmpeg 3.1 and later).")
endif()
endif()
if (ENABLE_FFMPEG_VIDEO_DUMPER)
add_definitions(-DENABLE_FFMPEG_VIDEO_DUMPER)
endif()
if (ENABLE_FDK)
find_library(FDK_AAC fdk-aac DOC "The path to fdk_aac library")
if(FDK_AAC STREQUAL "FDK_AAC-NOTFOUND")
message(FATAL_ERROR "fdk_aac library not found.")
endif()
endif()
# Platform-specific library requirements
# ======================================
if (APPLE)
# Umbrella framework for everything GUI-related
find_library(COCOA_LIBRARY Cocoa)
find_library(AVFOUNDATION_LIBRARY AVFoundation)
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
if (NOT USE_SYSTEM_MOLTENVK)
download_moltenvk()
endif()
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
if (NOT IOS)
# Umbrella framework for everything GUI-related
find_library(COCOA_LIBRARY Cocoa REQUIRED)
endif()
find_library(AVFOUNDATION_LIBRARY AVFoundation REQUIRED)
find_library(IOSURFACE_LIBRARY IOSurface REQUIRED)
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${AVFOUNDATION_LIBRARY} ${IOSURFACE_LIBRARY} ${MOLTENVK_LIBRARY})
elseif (WIN32)
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
set(PLATFORM_LIBRARIES winmm ws2_32)
if (MINGW)
# PSAPI is the Process Status API
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version crypt32)
endif()
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
set(PLATFORM_LIBRARIES rt)
@ -341,7 +358,7 @@ endif()
# against all the src files. This should be used before making a pull request.
# =======================================================================
set(CLANG_FORMAT_POSTFIX "-10")
set(CLANG_FORMAT_POSTFIX "-15")
find_program(CLANG_FORMAT
NAMES clang-format${CLANG_FORMAT_POSTFIX}
clang-format
@ -369,13 +386,15 @@ if (CLANG_FORMAT)
set(SRCS ${PROJECT_SOURCE_DIR}/src)
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
if (WIN32)
add_custom_target(clang-format
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
COMMENT ${CCOMMENT})
elseif(MINGW)
add_custom_target(clang-format
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp -o -iname *.mm | xargs `cygpath -u ${CLANG_FORMAT}` -i
COMMENT ${CCOMMENT})
if(MINGW)
add_custom_target(clang-format
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp -o -iname *.mm | xargs `cygpath -u ${CLANG_FORMAT}` -i
COMMENT ${CCOMMENT})
else()
add_custom_target(clang-format
COMMAND powershell.exe -Command "Get-ChildItem '${SRCS}/*' -Include *.cpp,*.h,*.mm -Recurse | Foreach {&'${CLANG_FORMAT}' -i $_.fullname}"
COMMENT ${CCOMMENT})
endif()
else()
add_custom_target(clang-format
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp -o -iname *.mm | xargs ${CLANG_FORMAT} -i
@ -412,13 +431,6 @@ function(get_timestamp _var)
set(${_var} "${timestamp}" PARENT_SCOPE)
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
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REF_SPEC GIT_REV)
@ -426,19 +438,48 @@ git_describe(GIT_DESC --always --long --dirty)
git_branch_name(GIT_BRANCH)
get_timestamp(BUILD_DATE)
if (NOT USE_SYSTEM_BOOST)
add_definitions( -DBOOST_ALL_NO_LIB )
# Boost
# 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
)
if (USE_SYSTEM_BOOST)
find_package(Boost 1.70.0 COMPONENTS container locale serialization iostreams REQUIRED)
endif()
enable_testing()
add_subdirectory(externals)
# Boost
if (USE_SYSTEM_BOOST)
find_package(Boost 1.70.0 COMPONENTS serialization REQUIRED)
else()
# Boost (bundled)
if (NOT USE_SYSTEM_BOOST)
add_definitions( -DBOOST_ALL_NO_LIB )
add_library(Boost::boost ALIAS boost)
add_library(Boost::serialization ALIAS boost_serialization)
add_library(Boost::iostreams ALIAS boost_iostreams)
endif()
# SDL2
if (ENABLE_SDL2 AND USE_SYSTEM_SDL2)
find_package(SDL2 REQUIRED)
add_library(SDL2 INTERFACE)
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
add_library(SDL2::SDL2 ALIAS SDL2)
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)
@ -452,6 +493,20 @@ else()
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT citra)
endif()
# Create target for outputting distributable bundles.
if (CITRA_ENABLE_BUNDLE_TARGET)
include(BundleTarget)
if (ENABLE_SDL2_FRONTEND)
bundle_target(citra)
endif()
if (ENABLE_QT)
bundle_target(citra-qt)
endif()
if (ENABLE_DEDICATED_ROOM)
bundle_target(citra-room)
endif()
endif()
# Installation instructions
# =========================
@ -460,7 +515,7 @@ endif()
# http://standards.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html
# http://standards.freedesktop.org/shared-mime-info-spec/shared-mime-info-spec-latest.html
if(ENABLE_QT AND UNIX AND NOT APPLE)
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.desktop"
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra-qt.desktop"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/applications")
install(FILES "${PROJECT_SOURCE_DIR}/dist/citra.svg"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps")

View File

@ -1,4 +1,5 @@
# To use this as a script, make sure you pass in the variables 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)
set(PLATFORM "windows")
@ -10,29 +11,16 @@ else()
message(FATAL_ERROR "Cannot build installer for this unsupported platform")
endif()
set(DIST_DIR "${BUILD_DIR}/dist")
set(ARCHIVE "${PLATFORM}.7z")
list(APPEND CMAKE_MODULE_PATH "${BASE_DIR}/CMakeModules")
include(DownloadExternals)
download_qt(tools_ifw)
get_external_prefix(qt QT_PREFIX)
file(MAKE_DIRECTORY ${BUILD_DIR})
file(MAKE_DIRECTORY ${DIST_DIR})
file(DOWNLOAD https://github.com/citra-emu/ext-windows-bin/raw/master/qtifw/${ARCHIVE}
"${BUILD_DIR}/${ARCHIVE}" SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${BUILD_DIR}/${ARCHIVE}"
WORKING_DIRECTORY "${BUILD_DIR}/")
file(GLOB_RECURSE INSTALLER_BASE "${QT_PREFIX}/**/installerbase*")
file(GLOB_RECURSE BINARY_CREATOR "${QT_PREFIX}/**/binarycreator*")
set(TARGET_NAME "citra-setup-${PLATFORM}")
set(CONFIG_FILE "${SRC_DIR}/config/config_${PLATFORM}.xml")
set(INSTALLER_BASE "${BUILD_DIR}/installerbase_${PLATFORM}")
set(BINARY_CREATOR "${BUILD_DIR}/binarycreator_${PLATFORM}")
set(PACKAGES_DIR "${BUILD_DIR}/packages")
file(MAKE_DIRECTORY ${PACKAGES_DIR})
if (UNIX OR APPLE)
execute_process(COMMAND chmod 744 ${BINARY_CREATOR})
endif()
execute_process(COMMAND ${BINARY_CREATOR} -t ${INSTALLER_BASE} -n -c ${CONFIG_FILE} -p ${PACKAGES_DIR} ${TARGET_FILE})
if (APPLE)
execute_process(COMMAND chmod 744 ${TARGET_FILE}.app/Contents/MacOS/${TARGET_NAME})
endif()

View File

@ -0,0 +1,277 @@
if (BUNDLE_TARGET_EXECUTE)
# --- Bundling method logic ---
function(bundle_qt executable_path)
if (WIN32)
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
find_program(windeployqt_executable windeployqt6)
# Create a qt.conf file pointing to the app directory.
# This ensures Qt can find its plugins.
file(WRITE "${executable_parent_dir}/qt.conf" "[Paths]\nprefix = .")
message(STATUS "Executing windeployqt for executable ${executable_path}")
execute_process(COMMAND "${windeployqt_executable}" "${executable_path}"
--no-compiler-runtime --no-system-d3d-compiler --no-opengl-sw --no-translations
--plugindir "${executable_parent_dir}/plugins")
# Remove the FFmpeg multimedia plugin as we don't include FFmpeg.
# We want to use the Windows media plugin instead, which is also included.
file(REMOVE "${executable_parent_dir}/plugins/multimedia/ffmpegmediaplugin.dll")
elseif (APPLE)
get_filename_component(executable_name "${executable_path}" NAME_WE)
find_program(MACDEPLOYQT_EXECUTABLE macdeployqt6)
message(STATUS "Executing macdeployqt for executable ${executable_path}")
execute_process(
COMMAND "${MACDEPLOYQT_EXECUTABLE}"
"${executable_path}"
"-executable=${executable_path}/Contents/MacOS/${executable_name}"
-always-overwrite)
# 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.
execute_process(COMMAND codesign --deep -fs - "${executable_path}")
else()
message(FATAL_ERROR "Unsupported OS for Qt bundling.")
endif()
endfunction()
function(bundle_appimage bundle_dir executable_path source_path binary_path linuxdeploy_executable enable_qt)
get_filename_component(executable_name "${executable_path}" NAME_WE)
set(appdir_path "${binary_path}/AppDir-${executable_name}")
if (enable_qt)
# Find qmake to make sure the plugin uses the right version of Qt.
find_program(QMAKE_EXECUTABLE qmake6)
set(extra_linuxdeploy_env "QMAKE=${QMAKE_EXECUTABLE}")
set(extra_linuxdeploy_args --plugin qt)
endif()
message(STATUS "Creating AppDir for executable ${executable_path}")
execute_process(COMMAND ${CMAKE_COMMAND} -E env
${extra_linuxdeploy_env}
"${linuxdeploy_executable}"
${extra_linuxdeploy_args}
--plugin checkrt
--executable "${executable_path}"
--icon-file "${source_path}/dist/citra.svg"
--desktop-file "${source_path}/dist/${executable_name}.desktop"
--appdir "${appdir_path}")
if (enable_qt)
set(qt_hook_file "${appdir_path}/apprun-hooks/linuxdeploy-plugin-qt-hook.sh")
file(READ "${qt_hook_file}" qt_hook_contents)
# Add Cinnamon to list of DEs for GTK3 theming.
string(REPLACE
"*XFCE*"
"*X-Cinnamon*|*XFCE*"
qt_hook_contents "${qt_hook_contents}")
# Wayland backend crashes due to changed schemas in Gnome 40.
string(REPLACE
"export QT_QPA_PLATFORMTHEME=gtk3"
"export QT_QPA_PLATFORMTHEME=gtk3; export GDK_BACKEND=x11"
qt_hook_contents "${qt_hook_contents}")
file(WRITE "${qt_hook_file}" "${qt_hook_contents}")
endif()
message(STATUS "Creating AppImage for executable ${executable_path}")
execute_process(COMMAND ${CMAKE_COMMAND} -E env
"OUTPUT=${bundle_dir}/${executable_name}.AppImage"
"${linuxdeploy_executable}"
--output appimage
--appdir "${appdir_path}")
endfunction()
function(bundle_standalone executable_path original_executable_path bundle_library_paths)
get_filename_component(executable_parent_dir "${executable_path}" DIRECTORY)
# Resolve dependent library files if they were not passed in.
message(STATUS "Determining runtime dependencies of ${executable_path} using library paths ${bundle_library_paths}")
file(GET_RUNTIME_DEPENDENCIES
EXECUTABLES ${original_executable_path}
RESOLVED_DEPENDENCIES_VAR resolved_deps
UNRESOLVED_DEPENDENCIES_VAR unresolved_deps
DIRECTORIES ${bundle_library_paths}
POST_EXCLUDE_REGEXES ".*system32.*")
if (WIN32)
# Same directory since we don't have rpath.
set(lib_dir "${executable_parent_dir}")
else()
set(lib_dir "${executable_parent_dir}/libs")
endif()
# Copy files to bundled output.
if (resolved_deps)
file(MAKE_DIRECTORY ${lib_dir})
foreach (lib_file IN LISTS resolved_deps)
message(STATUS "Bundling library ${lib_file}")
# Use native copy to turn symlinks into normal files.
execute_process(COMMAND cp -L "${lib_file}" "${lib_dir}")
endforeach()
endif()
# Add libs directory to executable rpath where applicable.
if (APPLE)
execute_process(COMMAND install_name_tool -add_rpath "@loader_path/libs" "${executable_path}")
elseif (UNIX)
execute_process(COMMAND patchelf --set-rpath '$ORIGIN/../libs' "${executable_path}")
endif()
endfunction()
# --- Root bundling logic ---
set(bundle_dir ${BINARY_PATH}/bundle)
# On Linux, always bundle an AppImage.
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})
else()
if (IN_PLACE)
message(STATUS "Bundling dependencies in-place")
set(bundled_executable_path "${EXECUTABLE_PATH}")
else()
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)
bundle_qt("${bundled_executable_path}")
endif()
if (WIN32 OR NOT BUNDLE_QT)
bundle_standalone("${bundled_executable_path}" "${EXECUTABLE_PATH}" "${BUNDLE_LIBRARY_PATHS}")
endif()
endif()
else()
# --- Bundling target creation logic ---
# Downloads and extracts a linuxdeploy component.
function(download_linuxdeploy_component base_dir name executable_name)
set(executable_file "${base_dir}/${executable_name}")
if (NOT EXISTS "${executable_file}")
message(STATUS "Downloading ${executable_name}")
file(DOWNLOAD
"https://github.com/linuxdeploy/${name}/releases/download/continuous/${executable_name}"
"${executable_file}" SHOW_PROGRESS)
file(CHMOD "${executable_file}" PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE)
get_filename_component(executable_ext "${executable_file}" LAST_EXT)
if (executable_ext STREQUAL ".AppImage")
message(STATUS "Extracting ${executable_name}")
execute_process(
COMMAND "${executable_file}" --appimage-extract
WORKING_DIRECTORY "${base_dir}")
else()
message(STATUS "Copying ${executable_name}")
file(COPY "${executable_file}" DESTINATION "${base_dir}/squashfs-root/usr/bin/")
endif()
endif()
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)
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")
endif()
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_FILE:${target_name}>")
if (target_name MATCHES ".*qt")
set(BUNDLE_QT ON)
if (APPLE)
# For Qt targets on Apple, expect an app bundle.
set(BUNDLE_EXECUTABLE_PATH "$<TARGET_BUNDLE_DIR:${target_name}>")
endif()
else()
set(BUNDLE_QT OFF)
endif()
# Build a list of library search paths from prefix paths.
foreach(prefix_path IN LISTS CMAKE_PREFIX_PATH CMAKE_SYSTEM_PREFIX_PATH)
if (WIN32)
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/bin")
endif()
list(APPEND BUNDLE_LIBRARY_PATHS "${prefix_path}/lib")
endforeach()
foreach(library_path IN LISTS CMAKE_SYSTEM_LIBRARY_PATH)
list(APPEND BUNDLE_LIBRARY_PATHS "${library_path}")
endforeach()
# On Linux, prepare linuxdeploy and any required plugins.
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUXDEPLOY_BASE "${CMAKE_BINARY_DIR}/externals/linuxdeploy")
# Download plugins first so they don't overwrite linuxdeploy's AppRun file.
download_linuxdeploy_component("${LINUXDEPLOY_BASE}" "linuxdeploy-plugin-qt" "linuxdeploy-plugin-qt-x86_64.AppImage")
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()
if (in_place)
message(STATUS "Adding in-place bundling to ${target_name}")
set(DEST_TARGET ${target_name})
else()
message(STATUS "Adding ${target_name} to bundle target")
set(DEST_TARGET bundle)
add_dependencies(bundle ${target_name})
endif()
add_custom_command(TARGET ${DEST_TARGET} POST_BUILD
COMMAND ${CMAKE_COMMAND}
"-DCMAKE_PREFIX_PATH=\"${CMAKE_PREFIX_PATH}\""
"-DBUNDLE_TARGET_EXECUTE=1"
"-DTARGET=${target_name}"
"-DSOURCE_PATH=${CMAKE_SOURCE_DIR}"
"-DBINARY_PATH=${CMAKE_BINARY_DIR}"
"-DEXECUTABLE_PATH=${BUNDLE_EXECUTABLE_PATH}"
"-DBUNDLE_LIBRARY_PATHS=\"${BUNDLE_LIBRARY_PATHS}\""
"-DBUNDLE_QT=${BUNDLE_QT}"
"-DIN_PLACE=${in_place}"
${EXTRA_BUNDLE_ARGS}
-P "${CMAKE_SOURCE_DIR}/CMakeModules/BundleTarget.cmake"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
endfunction()
# 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()
endif()

View File

@ -1,11 +0,0 @@
function(copy_citra_FFmpeg_deps target_dir)
include(WindowsCopyFiles)
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
windows_copy_files(${target_dir} ${FFMPEG_DIR}/bin ${DLL_DEST}
avcodec*.dll
avformat*.dll
avutil*.dll
swresample*.dll
swscale*.dll
)
endfunction(copy_citra_FFmpeg_deps)

View File

@ -1,46 +0,0 @@
function(copy_citra_Qt5_deps target_dir)
include(WindowsCopyFiles)
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
set(Qt5_MEDIASERVICE_DIR "${Qt5_DIR}/../../../plugins/mediaservice/")
set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/")
set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/")
set(PLATFORMS ${DLL_DEST}plugins/platforms/)
set(MEDIASERVICE ${DLL_DEST}plugins/mediaservice/)
set(STYLES ${DLL_DEST}plugins/styles/)
set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/)
windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
icudt*.dll
icuin*.dll
icuuc*.dll
Qt5Core$<$<CONFIG:Debug>:d>.*
Qt5Gui$<$<CONFIG:Debug>:d>.*
Qt5Widgets$<$<CONFIG:Debug>:d>.*
Qt5Multimedia$<$<CONFIG:Debug>:d>.*
Qt5Network$<$<CONFIG:Debug>:d>.*
)
windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
windows_copy_files(citra-qt ${Qt5_MEDIASERVICE_DIR} ${MEDIASERVICE}
dsengine$<$<CONFIG:Debug>:d>.*
wmfengine$<$<CONFIG:Debug>:d>.*
)
windows_copy_files(citra-qt ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
windows_copy_files(${target_dir} ${Qt5_IMAGEFORMATS_DIR} ${IMAGEFORMATS}
qgif$<$<CONFIG:Debug>:d>.dll
qicns$<$<CONFIG:Debug>:d>.dll
qico$<$<CONFIG:Debug>:d>.dll
qjpeg$<$<CONFIG:Debug>:d>.dll
qsvg$<$<CONFIG:Debug>:d>.dll
qtga$<$<CONFIG:Debug>:d>.dll
qtiff$<$<CONFIG:Debug>:d>.dll
qwbmp$<$<CONFIG:Debug>:d>.dll
qwebp$<$<CONFIG:Debug>:d>.dll
)
# Create an empty qt.conf file. Qt will detect that this file exists, and use the folder that its in as the root folder.
# This way it'll look for plugins in the root/plugins/ folder
add_custom_command(TARGET citra-qt POST_BUILD
COMMAND ${CMAKE_COMMAND} -E touch ${DLL_DEST}qt.conf
)
endfunction(copy_citra_Qt5_deps)

View File

@ -1,5 +0,0 @@
function(copy_citra_SDL_deps target_dir)
include(WindowsCopyFiles)
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
windows_copy_files(${target_dir} ${SDL2_DLL_DIR} ${DLL_DEST} SDL2.dll)
endfunction(copy_citra_SDL_deps)

View File

@ -1,18 +1,139 @@
# This function downloads a binary library package from our external repo.
set(CURRENT_MODULE_DIR ${CMAKE_CURRENT_LIST_DIR})
# This function downloads Qt using aqt. The path of the downloaded content will be added to the CMAKE_PREFIX_PATH.
# Params:
# remote_path: path to the file to download, relative to the remote repository root
# prefix_var: name of a variable which will be set with the path to the extracted contents
function(download_bundled_external remote_path lib_name prefix_var)
set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}")
if (NOT EXISTS "${prefix}")
message(STATUS "Downloading binaries for ${lib_name}...")
file(DOWNLOAD
https://github.com/citra-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z
"${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
endif()
message(STATUS "Using bundled binaries at ${prefix}")
set(${prefix_var} "${prefix}" PARENT_SCOPE)
endfunction()
# target: Qt dependency to install. Specify a version number to download Qt, or "tools_(name)" for a specific build tool.
function(download_qt target)
if (target MATCHES "tools_.*")
set(DOWNLOAD_QT_TOOL ON)
else()
set(DOWNLOAD_QT_TOOL OFF)
endif()
# Determine installation parameters for OS, architecture, and compiler
if (WIN32)
set(host "windows")
set(type "desktop")
if (NOT DOWNLOAD_QT_TOOL)
if (MINGW)
set(arch "win64_mingw")
set(arch_path "mingw_64")
elseif (MSVC)
if ("arm64" IN_LIST ARCHITECTURE)
set(arch_path "msvc2019_arm64")
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}")
else()
message(FATAL_ERROR "Unsupported bundled Qt toolchain. Enable USE_SYSTEM_QT and provide your own.")
endif()
endif()
elseif (APPLE)
set(host "mac")
if (IOS AND NOT DOWNLOAD_QT_TOOL)
set(type "ios")
set(arch "ios")
set(arch_path "ios")
set(host_arch_path "macos")
else()
set(type "desktop")
set(arch "clang_64")
set(arch_path "macos")
endif()
else()
set(host "linux")
set(type "desktop")
set(arch "gcc_64")
set(arch_path "linux")
endif()
get_external_prefix(qt base_path)
file(MAKE_DIRECTORY "${base_path}")
set(install_args -c "${CURRENT_MODULE_DIR}/aqt_config.ini")
if (DOWNLOAD_QT_TOOL)
set(prefix "${base_path}/Tools")
set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target})
else()
set(prefix "${base_path}/${target}/${arch_path}")
if (host_arch_path)
set(host_flag "--autodesktop")
set(host_prefix "${base_path}/${target}/${host_arch_path}")
endif()
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} ${host_flag}
-m qtmultimedia --archives qttranslations qttools qtsvg qtbase)
endif()
if (NOT EXISTS "${prefix}")
message(STATUS "Downloading binaries for Qt...")
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.1.9")
if (WIN32)
set(aqt_path "${base_path}/aqt.exe")
file(DOWNLOAD
${AQT_PREBUILD_BASE_URL}/aqt.exe
${aqt_path} SHOW_PROGRESS)
execute_process(COMMAND ${aqt_path} ${install_args}
WORKING_DIRECTORY ${base_path})
elseif (APPLE)
set(aqt_path "${base_path}/aqt-macos")
file(DOWNLOAD
${AQT_PREBUILD_BASE_URL}/aqt-macos
${aqt_path} SHOW_PROGRESS)
execute_process(COMMAND chmod +x ${aqt_path})
execute_process(COMMAND ${aqt_path} ${install_args}
WORKING_DIRECTORY ${base_path})
else()
# aqt does not offer binary releases for other platforms, so download and run from pip.
set(aqt_install_path "${base_path}/aqt")
file(MAKE_DIRECTORY "${aqt_install_path}")
execute_process(COMMAND python3 -m pip install --target=${aqt_install_path} aqtinstall
WORKING_DIRECTORY ${base_path})
execute_process(COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${aqt_install_path} python3 -m aqt ${install_args}
WORKING_DIRECTORY ${base_path})
endif()
endif()
message(STATUS "Using downloaded Qt binaries at ${prefix}")
# Add the Qt prefix path so CMake can locate it.
list(APPEND CMAKE_PREFIX_PATH "${prefix}")
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()
function(download_moltenvk)
if (IOS)
set(MOLTENVK_PLATFORM "iOS")
else()
set(MOLTENVK_PLATFORM "macOS")
endif()
set(MOLTENVK_DIR "${CMAKE_BINARY_DIR}/externals/MoltenVK")
set(MOLTENVK_TAR "${CMAKE_BINARY_DIR}/externals/MoltenVK.tar")
if (NOT EXISTS ${MOLTENVK_DIR})
if (NOT EXISTS ${MOLTENVK_TAR})
file(DOWNLOAD https://github.com/KhronosGroup/MoltenVK/releases/latest/download/MoltenVK-all.tar
${MOLTENVK_TAR} SHOW_PROGRESS)
endif()
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${MOLTENVK_TAR}"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
endif()
# Add the MoltenVK library path to the prefix so find_library can locate it.
list(APPEND CMAKE_PREFIX_PATH "${MOLTENVK_DIR}/MoltenVK/dylib/${MOLTENVK_PLATFORM}")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} PARENT_SCOPE)
endfunction()
function(get_external_prefix lib_name prefix_var)
set(${prefix_var} "${CMAKE_BINARY_DIR}/externals/${lib_name}" PARENT_SCOPE)
endfunction()

View File

@ -0,0 +1,65 @@
# Gets a UTC timstamp and sets the provided variable to it
function(get_timestamp _var)
string(TIMESTAMP timestamp UTC)
set(${_var} "${timestamp}" PARENT_SCOPE)
endfunction()
get_timestamp(BUILD_DATE)
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
if (EXISTS "${SRC_DIR}/.git/objects")
# Find the package here with the known path so that the GetGit commands can find it as well
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
# only use Git to check revision info when source is obtained via Git
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REF_SPEC GIT_REV)
git_describe(GIT_DESC --always --long --dirty)
git_branch_name(GIT_BRANCH)
elseif (EXISTS "${SRC_DIR}/GIT-COMMIT" AND EXISTS "${SRC_DIR}/GIT-TAG")
# unified source archive
file(READ "${SRC_DIR}/GIT-COMMIT" GIT_REV_RAW LIMIT 64)
string(STRIP "${GIT_REV_RAW}" GIT_REV)
string(SUBSTRING "${GIT_REV_RAW}" 0 9 GIT_DESC)
set(GIT_BRANCH "HEAD")
else()
# self-packed archive?
set(GIT_REV "UNKNOWN")
set(GIT_DESC "UNKNOWN")
set(GIT_BRANCH "UNKNOWN")
endif()
string(SUBSTRING "${GIT_REV}" 0 7 GIT_SHORT_REV)
# Generate cpp with Git revision from template
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
set(REPO_NAME "")
set(BUILD_VERSION "0")
set(BUILD_FULLNAME "${GIT_SHORT_REV}")
if (DEFINED ENV{CI})
if (DEFINED ENV{GITHUB_ACTIONS})
set(BUILD_REPOSITORY $ENV{GITHUB_REPOSITORY})
set(BUILD_TAG $ENV{GITHUB_REF_NAME})
endif()
# regex capture the string nightly or canary into CMAKE_MATCH_1
string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
if ("${CMAKE_MATCH_COUNT}" GREATER 0)
# capitalize the first letter of each word in the repo name.
string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
foreach(WORD ${REPO_NAME_LIST})
string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER}")
endforeach()
string(REGEX MATCH "${CMAKE_MATCH_1}-([0-9]+)" OUTVAR ${BUILD_TAG})
if (${CMAKE_MATCH_COUNT} GREATER 0)
set(BUILD_VERSION ${CMAKE_MATCH_1})
endif()
if (BUILD_VERSION)
set(BUILD_FULLNAME "${REPO_NAME} ${BUILD_VERSION}")
else()
set(BUILD_FULLNAME "")
endif()
endif()
endif()

View File

@ -1,73 +1,29 @@
# Gets a UTC timstamp and sets the provided variable to it
function(get_timestamp _var)
string(TIMESTAMP timestamp UTC)
set(${_var} "${timestamp}" PARENT_SCOPE)
endfunction()
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/externals/cmake-modules")
# Find the package here with the known path so that the GetGit commands can find it as well
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
# generate git/build information
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REF_SPEC GIT_REV)
git_describe(GIT_DESC --always --long --dirty)
git_branch_name(GIT_BRANCH)
get_timestamp(BUILD_DATE)
# Generate cpp with Git revision from template
# Also if this is a CI build, add the build name (ie: Nightly, Canary) to the scm_rev file as well
set(REPO_NAME "")
set(BUILD_VERSION "0")
if (DEFINED ENV{CI})
if (DEFINED ENV{GITHUB_ACTIONS})
set(BUILD_REPOSITORY $ENV{GITHUB_REPOSITORY})
set(BUILD_TAG $ENV{GIT_TAG_NAME})
elseif(DEFINED ENV{APPVEYOR})
set(BUILD_REPOSITORY $ENV{APPVEYOR_REPO_NAME})
set(BUILD_TAG $ENV{APPVEYOR_REPO_TAG_NAME})
elseif(DEFINED ENV{BITRISE_IO})
set(BUILD_REPOSITORY "$ENV{BITRISEIO_GIT_REPOSITORY_OWNER}/$ENV{BITRISEIO_GIT_REPOSITORY_SLUG}")
set(BUILD_TAG $ENV{BITRISE_GIT_TAG})
endif()
# regex capture the string nightly or canary into CMAKE_MATCH_1
string(REGEX MATCH "citra-emu/citra-?(.*)" OUTVAR ${BUILD_REPOSITORY})
if ("${CMAKE_MATCH_COUNT}" GREATER 0)
# capitalize the first letter of each word in the repo name.
string(REPLACE "-" ";" REPO_NAME_LIST ${CMAKE_MATCH_1})
foreach(WORD ${REPO_NAME_LIST})
string(SUBSTRING ${WORD} 0 1 FIRST_LETTER)
string(SUBSTRING ${WORD} 1 -1 REMAINDER)
string(TOUPPER ${FIRST_LETTER} FIRST_LETTER)
set(REPO_NAME "${REPO_NAME}${FIRST_LETTER}${REMAINDER}")
endforeach()
if (BUILD_TAG)
string(REGEX MATCH "${CMAKE_MATCH_1}-([0-9]+)" OUTVAR ${BUILD_TAG})
if (${CMAKE_MATCH_COUNT} GREATER 0)
set(BUILD_VERSION ${CMAKE_MATCH_1})
endif()
if (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()
set(BUILD_FULLNAME "")
endif()
endif()
endif()
endif()
list(APPEND CMAKE_MODULE_PATH "${SRC_DIR}/CMakeModules")
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)
set(VIDEO_CORE "${SRC_DIR}/src/video_core")
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.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.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.h"
"${VIDEO_CORE}/pica.cpp"

View File

@ -1,12 +0,0 @@
# buildcache wrapper
OPTION(USE_CCACHE "Use buildcache for compilation" OFF)
IF(USE_CCACHE)
FIND_PROGRAM(CCACHE buildcache)
IF (CCACHE)
MESSAGE(STATUS "Using buildcache found in PATH")
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
ELSE(CCACHE)
MESSAGE(WARNING "USE_CCACHE enabled, but no buildcache executable found")
ENDIF(CCACHE)
ENDIF(USE_CCACHE)

View File

@ -1,54 +0,0 @@
SET(MINGW_PREFIX /usr/x86_64-w64-mingw32/)
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
# Actually a hack, w/o this will cause some strange errors
SET(CMAKE_HOST_WIN32 TRUE)
SET(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX})
SET(SDL2_PATH ${MINGW_PREFIX})
SET(MINGW_TOOL_PREFIX ${CMAKE_SYSTEM_PROCESSOR}-w64-mingw32-)
# Specify the cross compiler
SET(CMAKE_C_COMPILER ${MINGW_TOOL_PREFIX}gcc-posix)
SET(CMAKE_CXX_COMPILER ${MINGW_TOOL_PREFIX}g++-posix)
SET(CMAKE_RC_COMPILER ${MINGW_TOOL_PREFIX}windres)
# Mingw tools
SET(STRIP ${MINGW_TOOL_PREFIX}strip)
SET(WINDRES ${MINGW_TOOL_PREFIX}windres)
SET(ENV{PKG_CONFIG} ${MINGW_TOOL_PREFIX}pkg-config)
# ccache wrapper
OPTION(USE_CCACHE "Use ccache for compilation" OFF)
IF(USE_CCACHE)
FIND_PROGRAM(CCACHE ccache)
IF (CCACHE)
MESSAGE(STATUS "Using ccache found in PATH")
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
ELSE(CCACHE)
MESSAGE(WARNING "USE_CCACHE enabled, but no ccache found")
ENDIF(CCACHE)
ENDIF(USE_CCACHE)
# Search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# Echo modified cmake vars to screen for debugging purposes
IF(NOT DEFINED ENV{MINGW_DEBUG_INFO})
MESSAGE("")
MESSAGE("Custom cmake vars: (blank = system default)")
MESSAGE("-----------------------------------------")
MESSAGE("* CMAKE_C_COMPILER : ${CMAKE_C_COMPILER}")
MESSAGE("* CMAKE_CXX_COMPILER : ${CMAKE_CXX_COMPILER}")
MESSAGE("* CMAKE_RC_COMPILER : ${CMAKE_RC_COMPILER}")
MESSAGE("* WINDRES : ${WINDRES}")
MESSAGE("* ENV{PKG_CONFIG} : $ENV{PKG_CONFIG}")
MESSAGE("* STRIP : ${STRIP}")
MESSAGE("* USE_CCACHE : ${USE_CCACHE}")
MESSAGE("")
# So that the debug info only appears once
SET(ENV{MINGW_DEBUG_INFO} SHOWN)
ENDIF()

View File

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

View File

@ -0,0 +1,9 @@
SET(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_PROCESSOR x86_64)
SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
set(CMAKE_RANLIB x86_64-w64-mingw32-ranlib)
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)

189
Makefile
View File

@ -1,21 +1,8 @@
HAVE_DYNARMIC = 0
HAVE_FFMPEG = 0
HAVE_FFMPEG_STATIC = 0
HAVE_GLAD = 1
HAVE_SSE = 0
HAVE_RGLGEN = 0
HAVE_RPC = 1
FFMPEG_DISABLE_VDPAU ?= 0
HAVE_FFMPEG_CROSSCOMPILE ?= 0
FFMPEG_XC_CPU ?=
FFMPEG_XC_ARCH ?=
FFMPEG_XC_PREFIX ?=
FFMPEG_XC_SYSROOT ?=
FFMPEG_XC_NM ?=
FFMPEG_XC_AR ?=
FFMPEG_XC_AS ?=
FFMPEG_XC_CC ?=
FFMPEG_XC_LD ?=
TARGET_NAME := citra
EXTERNALS_DIR += ./externals
@ -84,33 +71,12 @@ ifeq ($(STATIC_LINKING), 1)
EXT := a
endif
GIT_REV := "$(shell git rev-parse HEAD || echo unknown)"
GIT_BRANCH := "$(shell git rev-parse --abbrev-ref HEAD || echo unknown)"
GIT_DESC := "$(shell git describe --always --long --dirty || echo unknown)"
BUILD_DATE := "$(shell date +'%d/%m/%Y_%H:%M')"
DEFINES += -DGIT_REV=\"$(GIT_REV)\" \
-DGIT_BRANCH=\"$(GIT_BRANCH)\" \
-DGIT_DESC=\"$(GIT_DESC)\" \
-DBUILD_NAME=\"citra-libretro\" \
-DBUILD_DATE=\"$(BUILD_DATE)\" \
-DBUILD_VERSION=\"$(GIT_BRANCH)-$(GIT_DESC)\" \
-DBUILD_FULLNAME=\"\" \
-DSHADER_CACHE_VERSION=\"0\"
ifeq ($(platform), unix)
EXT ?= so
TARGET := $(TARGET_NAME)_libretro.$(EXT)
fpic := -fPIC
SHARED := -shared -Wl,--version-script=$(SRC_DIR)/citra_libretro/link.T -Wl,--no-undefined
LIBS +=-lpthread -lGL -ldl
HAVE_FFMPEG = 1
HAVE_FFMPEG_STATIC = 1
ifeq ($(HAVE_FFMPEG_STATIC), 1)
LIBS += $(EXTERNALS_DIR)/ffmpeg/libavcodec/libavcodec.a $(EXTERNALS_DIR)/ffmpeg/libavutil/libavutil.a
else
LIBS += -lavcodec -lavutil
endif
#######################################
# Nintendo Switch (libnx)
@ -233,7 +199,7 @@ else ifneq (,$(findstring windows_msvc2019,$(platform)))
PATH := $(PATH):$(shell IFS=$$'\n'; cygpath "$(VsInstallRoot)/Common7/IDE")
export INCLUDE := $(INCLUDE);$(WindowsSDKSharedIncludeDir);$(WindowsSDKUCRTIncludeDir);$(WindowsSDKUMIncludeDir)
export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir);$(FFMPEGDIR)/Windows/$(TARGET_ARCH)/lib
export LIB := $(LIB);$(WindowsSDKUCRTLibDir);$(WindowsSDKUMLibDir)
TARGET := $(TARGET_NAME)_libretro.dll
PSS_STYLE :=2
LDFLAGS += -DLL
@ -279,64 +245,9 @@ else
endif
endif
# Set ffmpeg configure options
ifeq ($(HAVE_FFMPEG_STATIC), 1)
FFMPEG_CONF_OPTS =--disable-encoders --disable-decoders --enable-decoder=aac --enable-decoder=aac_fixed --enable-decoder=aac_latm --disable-programs
ifeq ($(FFMPEG_DISABLE_VDPAU), 1)
FFMPEG_CONF_OPTS += --disable-vdpau
endif
ifeq ($(HAVE_FFMPEG_CROSSCOMPILE), 1)
FFMPEG_CONF_OPTS+= --enable-cross-compile --target-os="linux"
ifeq ($(FFMPEG_XC_CPU),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_CPU provided)
else
FFMPEG_CONF_OPTS += --cpu="$(FFMPEG_XC_CPU)"
endif
ifeq ($(FFMPEG_XC_ARCH),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_ARCH provided)
else
FFMPEG_CONF_OPTS += --arch="$(FFMPEG_XC_ARCH)"
endif
ifeq ($(FFMPEG_XC_PREFIX),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_PREFIX provided)
else
FFMPEG_CONF_OPTS += --cross-prefix="$(FFMPEG_XC_PREFIX)"
endif
ifeq ($(FFMPEG_XC_SYSROOT),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_SYSROOT provided)
else
FFMPEG_CONF_OPTS += --sysroot="$(FFMPEG_XC_SYSROOT)" --sysinclude="$(FFMPEG_XC_SYSROOT)/usr/include"
endif
ifeq ($(FFMPEG_XC_NM),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_NM provided)
else
FFMPEG_CONF_OPTS += --nm="$(FFMPEG_XC_NM)"
endif
ifeq ($(FFMPEG_XC_AR),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_AR provided)
else
FFMPEG_CONF_OPTS += --ar="$(FFMPEG_XC_AR)"
endif
ifeq ($(FFMPEG_XC_AS),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_AS provided)
else
FFMPEG_CONF_OPTS += --as="$(FFMPEG_XC_AS)"
endif
ifeq ($(FFMPEG_XC_CC),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_CC provided)
else
FFMPEG_CONF_OPTS += --cc="$(FFMPEG_XC_CC)"
endif
ifeq ($(FFMPEG_XC_LD),)
$(error HAVE_FFMPEG_CROSSCOMPILE set, but no FFMPEG_XC_LD provided)
else
FFMPEG_CONF_OPTS += --ld="$(FFMPEG_XC_LD)"
endif
endif
endif
include Makefile.common
SOURCES_C += $(DYNARMICSOURCES_C) $(FAAD2SOURCES_C) $(LIBRESSLSOURCES_C)
SOURCES_CXX += $(DYNARMICSOURCES_CXX)
CPPFILES = $(filter %.cpp,$(SOURCES_CXX))
@ -345,7 +256,7 @@ CCFILES = $(filter %.cc,$(SOURCES_CXX))
OBJECTS := $(SOURCES_C:.c=.o) $(CPPFILES:.cpp=.o) $(CCFILES:.cc=.o)
ifeq (,$(findstring msvc,$(platform)))
CXXFLAGS += -std=c++17
CXXFLAGS += -std=c++20
else
CXXFLAGS += -std:c++latest
endif
@ -356,7 +267,7 @@ DYNARMICFLAGS += -D__LIBRETRO__ $(fpic) $(DEFINES) $(DYNARMICINCFLAGS) $(INCFLAG
CXXFLAGS += -D__LIBRETRO__ $(fpic) $(DEFINES) $(INCFLAGS) $(INCFLAGS_PLATFORM)
OBJOUT = -o
LINKOUT = -o
LINKOUT = -o
ifneq (,$(findstring msvc,$(platform)))
OBJOUT = -Fo
@ -388,51 +299,93 @@ endif
all: shaders $(TARGET)
ffmpeg_configure:
ifeq ($(HAVE_FFMPEG_STATIC), 1)
cd $(EXTERNALS_DIR)/ffmpeg && ./configure $(FFMPEG_CONF_OPTS)
endif
ffmpeg_static: ffmpeg_configure
ifeq ($(HAVE_FFMPEG_STATIC), 1)
cd $(EXTERNALS_DIR)/ffmpeg && $(MAKE) -j$(NUMPROC)
endif
$(TARGET): ffmpeg_static $(OBJECTS)
$(TARGET): $(OBJECTS)
ifeq ($(STATIC_LINKING), 1)
$(AR) rcs $@ $(OBJECTS)
else
$(LD) $(fpic) $(SHARED) $(INCLUDES) $(LINKOUT)$@ $(OBJECTS) $(LDFLAGS) $(LIBS)
endif
%.o: %.c
$(CC) $(CFLAGS) $(fpic) -c $(OBJOUT)$@ $<
$(foreach p,$(OBJECTS),$(if $(findstring $(EXTERNALS_DIR)/dynarmic/src,$p),$p,)):
$(CXX) $(DYNARMICFLAGS) $(fpic) -c $(OBJOUT)$@ $(@:.o=.cpp)
$(foreach p,$(OBJECTS),$(if $(findstring $(EXTERNALS_DIR)/dynarmic/externals/mcl,$p),$p,)):
$(CXX) $(DYNARMICFLAGS) $(fpic) -c $(OBJOUT)$@ $(@:.o=.cpp)
$(foreach p,$(OBJECTS),$(if $(findstring $(EXTERNALS_DIR)/dynarmic/externals/zy,$p),$p,)):
$(CC) $(CFLAGS) $(DYNARMICINCFLAGS) $(fpic) -c $(OBJOUT)$@ $(@:.o=.c)
$(foreach p,$(OBJECTS),$(if $(findstring $(EXTERNALS_DIR)/faad2,$p),$p,)):
$(CC) $(CFLAGS) $(FAAD2FLAGS) $(fpic) -c $(OBJOUT)$@ $(@:.o=.c)
$(foreach p,$(OBJECTS),$(if $(findstring $(EXTERNALS_DIR)/libressl,$p),$p,)):
$(CC) $(LIBRESSLFLAGS) $(CFLAGS) $(fpic) -c $(OBJOUT)$@ $(@:.o=.c)
%.o: %.c
$(CC) $(CFLAGS) $(fpic) -c $(OBJOUT)$@ $<
%.o: %.cc
$(CXX) $(CXXFLAGS) $(fpic) -c $(OBJOUT)$@ $<
%.o: %.cpp
%.o: %.cpp $(EXTERNALS_DIR)/glslang/build/glslang/build_info.h
$(CXX) $(CXXFLAGS) $(fpic) -c $(OBJOUT)$@ $<
GIT_REV := $(shell git rev-parse HEAD || echo unknown)
GIT_BRANCH := $(shell git rev-parse --abbrev-ref HEAD || echo unknown)
GIT_DESC := $(shell git describe --always --long --dirty || echo unknown)
GIT_COMMIT_DATE := $(shell git log -n1 --date=format-local:'%y%m%d' --format='%cd')
BUILD_DATE := $(shell date +'%Y-%m-%d_%H:%M%z')
$(SRC_DIR)/common/scm_rev.cpp: $(SHADER_CACHE_DEPENDS)
cat src/common/scm_rev.cpp.in | sed -e 's/@GIT_REV@/$(GIT_REV)/' \
-e 's/@GIT_BRANCH@/$(GIT_BRANCH)/' \
-e 's/@GIT_DESC@/$(GIT_COMMIT_DATE)+$(GIT_DESC)/' \
-e 's/@REPO_NAME@/citra-libretro/' \
-e 's/@BUILD_DATE@/$(BUILD_DATE)/' \
-e 's/@BUILD_VERSION@/$(GIT_BRANCH)-$(GIT_DESC)/' \
-e 's/@BUILD_FULLNAME@//' \
-e 's/@SHADER_CACHE_VERSION@/$(shell sha1sum $(SHADER_CACHE_DEPENDS) | sha1sum | cut -d" " -f1)/' > $@
$(EXTERNALS_DIR)/glslang/build/glslang/build_info.h: $(EXTERNALS_DIR)/glslang/build_info.h.tmpl $(EXTERNALS_DIR)/glslang/CHANGES.md
python3 $(EXTERNALS_DIR)/glslang/build_info.py $(EXTERNALS_DIR)/glslang \
-i $(EXTERNALS_DIR)/glslang/build_info.h.tmpl \
-o $(EXTERNALS_DIR)/glslang/build/glslang/build_info.h
genfiles: $(SRC_DIR)/common/scm_rev.cpp $(EXTERNALS_DIR)/glslang/build/glslang/build_info.h
clean:
rm -f $(OBJECTS) $(TARGET)
ifeq ($(HAVE_FFMPEG_STATIC), 1)
cd $(EXTERNALS_DIR)/ffmpeg && $(MAKE) clean
rm -f $(OBJECTS) $(TARGET) $(SRC_DIR)/common/scm_rev.cpp
rm -rf $(SRC_DIR)/video_core/shaders
GLSLANG := glslang
ifeq (, $(shell which $(GLSLANG)))
GLSLANG := glslangValidator
ifeq (, $(shell which $(GLSLANG)))
$(error Required program `glslang` (or `glslangValidator`) not found.)
endif
endif
shaders: $(SHADER_FILES)
mkdir -p $(SRC_DIR)/video_core/shaders
for SHADER_FILE in $^; do \
OUT_DIR=$$(dirname "$(SRC_DIR)/video_core/shaders/$$SHADER_FILE"); \
FILENAME=$$(basename "$$SHADER_FILE"); \
SHADER_NAME=$$(echo "$$FILENAME" | sed -e "s/\./_/g"); \
rm -f $(SRC_DIR)/video_core/shaders/$$FILENAME; \
echo "#pragma once" >> $(SRC_DIR)/video_core/shaders/$$FILENAME; \
echo "constexpr std::string_view $$SHADER_NAME = R\"(" >> $(SRC_DIR)/video_core/shaders/$$FILENAME; \
cat $$SHADER_FILE >> $(SRC_DIR)/video_core/shaders/$$FILENAME; \
echo ")\";" >> $(SRC_DIR)/video_core/shaders/$$FILENAME; \
SHADER_NAME=$$(echo "$$FILENAME" | sed -e 's/\./_/g'); \
OUT_FILE="$$OUT_DIR/$$SHADER_NAME"; \
if [ "$$FILENAME" = "$${FILENAME#vulkan}" ]; then \
SHADER_CONTENT=$$(cat $$SHADER_FILE | sed -e 's/"/'\''/g'); \
SHADER_CONTENT=$$(echo "$$SHADER_CONTENT" | sed -e 's/.*/"&'\\\\\\\\'n"/'); \
mkdir -p "$$OUT_DIR"; \
echo "$$SHADER_CONTENT" > $$OUT_FILE; \
cat $(SRC_DIR)/video_core/host_shaders/source_shader.h.in | sed -e "s/@CONTENTS_NAME@/$$(echo $$SHADER_NAME | tr '[a-z]' '[A-Z]')/" > $$OUT_FILE.h; \
sed -i -e "/@CONTENTS@/ { r $$OUT_FILE" -e "d }" $$OUT_FILE.h; \
rm -f $$OUT_FILE; \
fi; \
if [ "$$FILENAME" = "$${FILENAME#opengl}" ]; then \
SHADER_NAME=$${SHADER_NAME}_spv; \
$(GLSLANG) --target-env vulkan1.1 --glsl-version 450 -Dgl_VertexID=gl_VertexIndex \
--variable-name $$(echo $$SHADER_NAME | tr '[a-z]' '[A-Z]') -o $${OUT_FILE}_spv.h $$SHADER_FILE; \
fi; \
done
.PHONY: clean ffmpeg_static
.PHONY: clean shaders genfiles

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,49 @@
**BEFORE FILING AN ISSUE, READ THE RELEVANT SECTION IN THE [CONTRIBUTING](https://github.com/citra-emu/citra/wiki/Contributing#reporting-issues) FILE!!!**
<h1 align="center">
<br>
<a href="https://citra-emu.org/"><img src="https://raw.githubusercontent.com/citra-emu/citra-assets/master/Main/citra_logo.svg" alt="Citra" width="200"></a>
<br>
<b>Citra</b>
<br>
</h1>
# Citra
<h4 align="center"><b>Citra</b> is the world's most popular, open-source, Nintendo 3DS emulator.
<br>
It is written in C++ with portability in mind and builds are actively maintained for Windows, Linux, Android and macOS.
</h4>
[![GitHub Actions Build Status](https://github.com/citra-emu/citra/workflows/citra-ci/badge.svg)](https://github.com/citra-emu/citra/actions)
[![Bitrise CI Build Status](https://app.bitrise.io/app/4ccd8e5720f0d13b/status.svg?token=H32TmbCwxb3OQ-M66KbAyw&branch=master)](https://app.bitrise.io/app/4ccd8e5720f0d13b)
[![Discord](https://img.shields.io/discord/220740965957107713?color=%237289DA&label=Citra&logo=discord&logoColor=white)](https://discord.gg/FAXfZV9)
<p align="center">
<a href="https://github.com/citra-emu/citra/actions/">
<img src="https://github.com/citra-emu/citra/workflows/citra-ci/badge.svg"
alt="GitHub Actions Build Status">
</a>
<a href="https://discord.gg/FAXfZV9">
<img src="https://img.shields.io/discord/220740965957107713?color=%237289DA&label=Citra&logo=discord&logoColor=white"
alt="Discord">
</a>
</p>
Citra is an experimental open-source Nintendo 3DS emulator/debugger written in C++. It is written with portability in mind, with builds actively maintained for Windows, Linux and macOS.
<p align="center">
<a href="#compatibility">Compatibility</a> |
<a href="#releases">Releases</a> |
<a href="#development">Development</a> |
<a href="#building">Building</a> |
<a href="#support">Support</a> |
<a href="#license">License</a>
</p>
Citra emulates a subset of 3DS hardware and therefore is useful for running/debugging homebrew applications, and it is also able to run many commercial games! Some of these do not run at a playable state, but we are working every day to advance the project forward. (Playable here means compatibility of at least "Okay" on our [game compatibility list](https://citra-emu.org/game).)
Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://citra-emu.org/wiki/faq/) before getting started with the project.
## Compatibility
Check out our [website](https://citra-emu.org/)!
The emulator is capable of running most commercial games at full speed, provided you meet the necessary hardware requirements.
For a full list of games Citra supports, please visit our [Compatibility page](https://citra-emu.org/game/)
Check out our [website](https://citra-emu.org/) for the latest news on exciting features, progress reports, and more!
Please read the [FAQ](https://citra-emu.org/wiki/faq/) before getting started with the project.
Need help? Check out our [asking for help](https://citra-emu.org/help/reference/asking/) guide.
For development discussion, please join us on our [Discord server](https://citra-emu.org/discord/) or at #citra-dev on libera.
### Releases
## Releases
Citra has two main release channels: Nightly and Canary.
@ -28,30 +53,46 @@ The [Canary](https://github.com/citra-emu/citra-canary) build is based on the ma
Both builds can be installed with the installer provided on the [website](https://citra-emu.org/download/), but those looking for specific versions or standalone releases can find them in the release tabs of the [Nightly](https://github.com/citra-emu/citra-nightly/releases) and [Canary](https://github.com/citra-emu/citra-canary/releases) repositories.
Currently, development and releases of the Android version are in [a separate repository](https://github.com/citra-emu/citra-android).
Android builds can be downloaded from the Google Play Store.
A Flatpak for Citra is available on [Flathub](https://flathub.org/apps/details/org.citra_emu.citra). Details on the build process can be found in [our Flathub repository](https://github.com/flathub/org.citra_emu.citra).
### Development
## Development
Most of the development happens on GitHub. It's also where [our central repository](https://github.com/citra-emu/citra) is hosted.
For development discussion, please join us on our [Discord server](https://citra-emu.org/discord/) or at #citra-dev on libera.
If you want to contribute please take a look at the [Contributor's Guide](https://github.com/citra-emu/citra/wiki/Contributing) and [Developer Information](https://github.com/citra-emu/citra/wiki/Developer-Information). You should also contact any of the developers in the forum in order to know about the current state of the emulator because the [TODO list](https://docs.google.com/document/d/1SWIop0uBI9IW8VGg97TAtoT_CHNoP42FzYmvG1F4QDA) isn't maintained anymore.
If you want to contribute please take a look at the [Contributor's Guide](https://github.com/citra-emu/citra/wiki/Contributing) and [Developer Information](https://github.com/citra-emu/citra/wiki/Developer-Information). You can also contact any of the developers on Discord in order to know about the current state of the emulator.
If you want to contribute to the user interface translation, please check out the [citra project on transifex](https://www.transifex.com/citra/citra). We centralize the translation work there, and periodically upstream translations.
If you want to contribute to the user interface translation, please check out the [Citra project on transifex](https://www.transifex.com/citra/citra). We centralize the translation work there, and periodically upstream translations.
### Building
## Building
* __Windows__: [Windows Build](https://github.com/citra-emu/citra/wiki/Building-For-Windows)
* __Linux__: [Linux Build](https://github.com/citra-emu/citra/wiki/Building-For-Linux)
* __macOS__: [macOS Build](https://github.com/citra-emu/citra/wiki/Building-for-macOS)
* __Android__: [Android Build](https://github.com/citra-emu/citra/wiki/Building-for-Android)
### Support
We happily accept monetary donations or donated games and hardware. Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra. Any donations received will go towards things like:
## Support
If you enjoy the project and want to support us financially, check out our Patreon!
<a href="https://www.patreon.com/citraemu">
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
</a>
We also happily accept donated games and hardware.
Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra.
Any donations received will go towards things like:
* 3DS consoles for developers to explore the hardware
* 3DS games for testing
* Any equipment required for homebrew
* Infrastructure setup
We also more than gladly accept used 3DS consoles! If you would like to give yours away, don't hesitate to join our [Discord server](https://citra-emu.org/discord/) and talk to bunnei.
## License
Citra is licensed under the GPLv2 (or any later version). Refer to the [LICENSE.txt](https://github.com/citra-emu/citra/blob/master/license.txt) file.

View File

@ -1,135 +0,0 @@
---
format_version: '6'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: android
trigger_map:
- push_branch: "*"
workflow: primary
- pull_request_source_branch: "*"
workflow: primary
workflows:
deploy:
description: |
## How to get a signed APK
This workflow contains the **Sign APK** step. To sign your APK all you have to do is to:
1. Click on **Code Signing** tab
1. Find the **ANDROID KEYSTORE FILE** section
1. Click or drop your file on the upload file field
1. Fill the displayed 3 input fields:
1. **Keystore password**
1. **Keystore alias**
1. **Private key password**
1. Click on **[Save metadata]** button
That's it! From now on, **Sign APK** step will receive your uploaded files.
## To run this workflow
If you want to run this workflow manually:
1. Open the app's build list page
2. Click on **[Start/Schedule a Build]** button
3. Select **deploy** in **Workflow** dropdown input
4. Click **[Start Build]** button
Or if you need this workflow to be started by a GIT event:
1. Click on **Triggers** tab
2. Setup your desired event (push/tag/pull) and select **deploy** workflow
3. Click on **[Done]** and then **[Save]** buttons
The next change in your repository that matches any of your trigger map event will start **deploy** workflow.
steps:
- cache-pull@2.4.0: {}
- script@1.1.6:
title: Install newer cmake
inputs:
- content: |-
#!/bin/bash
set -ex
sudo apt remove cmake -y
sudo apt purge --auto-remove cmake -y
sudo apt install ninja-build -y
version=3.19
build=2
mkdir ~/temp
cd ~/temp
wget https://cmake.org/files/v$version/cmake-$version.$build-Linux-x86_64.sh
sudo mkdir /opt/cmake
sudo sh cmake-$version.$build-Linux-x86_64.sh --prefix=/opt/cmake --skip-license --exclude-subdir
envman add --key PATH --value "/opt/cmake/bin:$PATH"
- install-missing-android-tools@2.3.8:
inputs:
- gradlew_path: "$PROJECT_LOCATION/gradlew"
- change-android-versioncode-and-versionname@1.1.1:
inputs:
- build_gradle_path: "$PROJECT_LOCATION/$MODULE/build.gradle"
- android-lint@0.9.8:
inputs:
- project_location: "$PROJECT_LOCATION"
- module: "$MODULE"
- variant: "$TEST_VARIANT"
- android-unit-test@0.9.3:
inputs:
- project_location: "$PROJECT_LOCATION"
- module: "$MODULE"
- variant: "$TEST_VARIANT"
- android-build@0.10.3:
inputs:
- project_location: "$PROJECT_LOCATION"
- module: "$MODULE"
- variant: "$BUILD_VARIANT"
- sign-apk@1.2.3:
run_if: '{{getenv "BITRISEIO_ANDROID_KEYSTORE_URL" | ne ""}}'
- deploy-to-bitrise-io@1.11.1: {}
- cache-push@2.4.1: {}
primary:
steps:
- cache-pull@2.4.0: {}
- script@1.1.6:
title: Install newer cmake
inputs:
- content: |-
#!/bin/bash
set -ex
sudo apt remove cmake -y
sudo apt purge --auto-remove cmake -y
sudo apt install ninja-build -y
version=3.19
build=2
mkdir ~/temp
cd ~/temp
wget https://cmake.org/files/v$version/cmake-$version.$build-Linux-x86_64.sh
sudo mkdir /opt/cmake
sudo sh cmake-$version.$build-Linux-x86_64.sh --prefix=/opt/cmake --skip-license --exclude-subdir
envman add --key PATH --value "/opt/cmake/bin:$PATH"
- install-missing-android-tools@2.3.8:
inputs:
- gradlew_path: "$PROJECT_LOCATION/gradlew"
- android-lint@0.9.8:
inputs:
- project_location: "$PROJECT_LOCATION"
- module: "$MODULE"
- variant: "$TEST_VARIANT"
- android-build@0.10.3:
inputs:
- variant: Debug
- project_location: "$PROJECT_LOCATION"
- deploy-to-bitrise-io@1.11.1: {}
- cache-push@2.4.1: {}
app:
envs:
- opts:
is_expand: false
PROJECT_LOCATION: src/android
- opts:
is_expand: false
MODULE: app
- opts:
is_expand: false
BUILD_VARIANT: Release
- opts:
is_expand: false
TEST_VARIANT: Debug

21
build-libretro-android.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
set -e
cd $(dirname $0)
[ -z "$NDK" ] && echo "You must specify ndk path in env like \"NDK=/path/to/android-ndk-r26b $0\"" && exit 1
ABI=arm64-v8a
MINSDKVERSION=21
mkdir -p build-android && cd build-android
cmake -DCMAKE_TOOLCHAIN_FILE=$NDK/build/cmake/android.toolchain.cmake \
-DANDROID_ABI=$ABI \
-DANDROID_PLATFORM=android-$MINSDKVERSION \
-DENABLE_TESTS=OFF -DENABLE_DEDICATED_ROOM=OFF \
-DENABLE_SDL2=OFF -DENABLE_QT=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_SCRIPTING=OFF \
-DENABLE_OPENAL=OFF -DENABLE_LIBUSB=OFF -DCITRA_ENABLE_BUNDLE_TARGET=OFF \
..
make -j$(nproc)
SO=citra_libretro.so
echo "Core file is here => $(readlink -f $SO)"
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip $SO

15
build-libretro-linux.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
set -e
cd $(dirname $0)
mkdir -p build-linux && cd build-linux
cmake -DENABLE_TESTS=OFF -DENABLE_DEDICATED_ROOM=OFF \
-DENABLE_SDL2=OFF -DENABLE_QT=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_SCRIPTING=OFF \
-DENABLE_OPENAL=OFF -DENABLE_LIBUSB=OFF -DCITRA_ENABLE_BUNDLE_TARGET=OFF \
..
make -j$(nproc)
SO=citra_libretro.so
echo "Core file is here => $(readlink -f $SO)"
strip $SO

18
build-libretro-windows.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
set -e
cd $(dirname $0)
mkdir -p build-windows && cd build-windows
cmake -DCMAKE_TOOLCHAIN_FILE=../CMakeModules/x86_64-w64-mingw32.cmake \
-DCITRA_WARNINGS_AS_ERRORS=OFF -DDISABLE_CLANG_TARGET=ON -DENABLE_LTO=OFF \
-DENABLE_TESTS=OFF -DENABLE_DEDICATED_ROOM=OFF \
-DENABLE_SDL2=OFF -DENABLE_QT=OFF -DENABLE_WEB_SERVICE=OFF -DENABLE_SCRIPTING=OFF \
-DENABLE_OPENAL=OFF -DENABLE_LIBUSB=OFF -DCITRA_ENABLE_BUNDLE_TARGET=OFF \
-DENABLE_CUBEB=OFF \
..
make -j$(nproc)
SO=bin/Release/citra_libretro.dll
echo "Core file is here => $(readlink -f $SO)"
x86_64-w64-mingw32-strip $SO

52
dist/apple/Info.plist.in vendored Normal file
View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Templated data -->
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleLongVersionString</key>
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleGetInfoString</key>
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>LSMinimumSystemVersion</key>
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
<!-- Fixed -->
<key>LSApplicationCategoryType</key>
<string>public.app-category.games</string>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access to emulate the 3DS&apos;s cameras.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to emulate the 3DS&apos;s microphone.</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CSResourcesFileMapped</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
</dict>
</plist>

42
dist/apple/LaunchScreen.storyboard vendored Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="Y6W-OH-hqX">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_logo.png" translatesAutoresizingMaskIntoConstraints="NO" id="yrZ-hu-Uge">
<rect key="frame" x="-59.666666666666657" y="306" width="512.33333333333337" height="240"/>
<constraints>
<constraint firstAttribute="height" constant="240" id="VhL-hA-Bwr"/>
</constraints>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="yrZ-hu-Uge" firstAttribute="centerX" secondItem="5EZ-qb-Rvc" secondAttribute="centerX" id="1y3-Mx-a65"/>
<constraint firstItem="yrZ-hu-Uge" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="vNO-xV-EPD"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="219" y="18"/>
</scene>
</scenes>
<resources>
<image name="launch_logo.png" width="512" height="512"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

BIN
dist/apple/launch_logo.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

15
dist/citra-qt.desktop vendored Normal file
View File

@ -0,0 +1,15 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=Citra
GenericName=3DS Emulator
GenericName[fr]=Émulateur 3DS
Comment=Nintendo 3DS video game console emulator
Comment[fr]=Émulateur de console de jeu Nintendo 3DS
Icon=citra
TryExec=citra-qt
Exec=citra-qt %f
Categories=Game;Emulator;Qt;
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
Keywords=3DS;Nintendo;
PrefersNonDefaultGPU=true

10
dist/citra-room.desktop vendored Normal file
View File

@ -0,0 +1,10 @@
[Desktop Entry]
Version=1.0
Type=Application
Name=Citra Room
Comment=Multiplayer room host for Citra
Icon=citra
TryExec=citra-room
Exec=citra-room %f
Categories=Game;Emulator;
Keywords=3DS;Nintendo

6
dist/citra.desktop vendored
View File

@ -7,9 +7,9 @@ GenericName[fr]=Émulateur 3DS
Comment=Nintendo 3DS video game console emulator
Comment[fr]=Émulateur de console de jeu Nintendo 3DS
Icon=citra
TryExec=citra-qt
Exec=citra-qt %f
Categories=Game;Emulator;Qt;
TryExec=citra
Exec=citra %f
Categories=Game;Emulator;
MimeType=application/x-ctr-3dsx;application/x-ctr-cci;application/x-ctr-cia;application/x-ctr-cxi;
Keywords=3DS;Nintendo;
PrefersNonDefaultGPU=true

291
dist/dumpkeys/DumpKeys.gm9 vendored Normal file
View File

@ -0,0 +1,291 @@
set PREVIEW_MODE "Key Dumper\n \nWorking..."
# Boot9
set BOOT9_BIN "M:/boot9.bin"
fget $[BOOT9_BIN]@D9D0:10 KEYX_2C
set KEYX_2D $[KEYX_2C]
set KEYX_2E $[KEYX_2C]
set KEYX_2F $[KEYX_2C]
fget $[BOOT9_BIN]@D9E0:10 KEYX_30
set KEYX_31 $[KEYX_30]
set KEYX_32 $[KEYX_30]
set KEYX_33 $[KEYX_30]
fget $[BOOT9_BIN]@D9F0:10 KEYX_34
set KEYX_35 $[KEYX_34]
set KEYX_36 $[KEYX_34]
set KEYX_37 $[KEYX_34]
fget $[BOOT9_BIN]@DA00:10 KEYX_38
set KEYX_39 $[KEYX_38]
set KEYX_3A $[KEYX_38]
set KEYX_3B $[KEYX_38]
fget $[BOOT9_BIN]@DA10:10 KEYX_3C
fget $[BOOT9_BIN]@DA20:10 KEYX_3D
fget $[BOOT9_BIN]@DA30:10 KEYX_3E
fget $[BOOT9_BIN]@DA40:10 KEYX_3F
fget $[BOOT9_BIN]@DA50:10 KEYY_04
fget $[BOOT9_BIN]@DA60:10 KEYY_05
fget $[BOOT9_BIN]@DA70:10 KEYY_06
fget $[BOOT9_BIN]@DA80:10 KEYY_07
fget $[BOOT9_BIN]@DA90:10 KEYY_08
fget $[BOOT9_BIN]@DAA0:10 KEYY_09
fget $[BOOT9_BIN]@DAB0:10 KEYY_0A
fget $[BOOT9_BIN]@DAC0:10 KEYY_0B
fget $[BOOT9_BIN]@DAD0:10 KEYN_0D
fget $[BOOT9_BIN]@DBA0:10 KEYN_2D
fget $[BOOT9_BIN]@DBB0:10 KEYN_32
fget $[BOOT9_BIN]@DBC0:10 KEYN_36
fget $[BOOT9_BIN]@DBD0:10 KEYN_38
# NATIVE_FIRM
if chk $[ONTYPE] "N3DS"
if not find 1:/title/00040138/20000002/content/????????.app NATIVE_FIRM_APP
echo "New 3DS NATIVE_FIRM not found."
goto Exit
end
set EXPECTED_NATIVE_FIRM_VER "1F00"
set KEYY_2E_OFFSET "66504"
set KEYY_39_NFC_OFFSET "66524"
set COMMON_0_OFFSET "6CE51"
set COMMON_1_OFFSET "6CE65"
set COMMON_2_OFFSET "6CE79"
set COMMON_3_OFFSET "6CE8D"
set COMMON_4_OFFSET "6CEA1"
set COMMON_5_OFFSET "6CEB5"
else
if not find 1:/title/00040138/00000002/content/????????.app NATIVE_FIRM_APP
echo "Old 3DS NATIVE_FIRM not found."
goto Exit
end
set EXPECTED_NATIVE_FIRM_VER "1F00"
set KEYY_2E_OFFSET "66488"
set KEYY_39_NFC_OFFSET "664A8"
set COMMON_0_OFFSET "6CDC1"
set COMMON_1_OFFSET "6CDD5"
set COMMON_2_OFFSET "6CDE9"
set COMMON_3_OFFSET "6CDFD"
set COMMON_4_OFFSET "6CE11"
set COMMON_5_OFFSET "6CE25"
end
set NATIVE_FIRM_EXTHEADER "G:/extheader.bin"
set NATIVE_FIRM_ENCRYPTED "G:/exefs/.firm"
set NATIVE_FIRM_DECRYPTED "$[GM9OUT]/native.firm"
set PROCESS9_CODE "G:/0004013000003000.Process9/exefs/.code"
imgmount $[NATIVE_FIRM_APP]
fget $[NATIVE_FIRM_EXTHEADER]@E:2 NATIVE_FIRM_VER
if not chk $[NATIVE_FIRM_VER] $[EXPECTED_NATIVE_FIRM_VER]
echo "Unsupported NATIVE_FIRM version.\nThis script requires the latest 3DS firmware.\n\nExpected $[EXPECTED_NATIVE_FIRM_VER], got $[NATIVE_FIRM_VER]"
goto Exit
end
cp -w $[NATIVE_FIRM_ENCRYPTED] $[NATIVE_FIRM_DECRYPTED]
decrypt $[NATIVE_FIRM_DECRYPTED]
imgumount
imgmount $[NATIVE_FIRM_DECRYPTED]
fget $[PROCESS9_CODE]@$[KEYY_2E_OFFSET]:10 KEYY_2E
set KEYY_31 $[KEYY_2E]
set KEYY_39_DLP $[KEYY_2E]
fget $[PROCESS9_CODE]@$[KEYY_39_NFC_OFFSET]:10 KEYY_39_NFC
fget $[PROCESS9_CODE]@$[COMMON_0_OFFSET]:10 COMMON_0
fget $[PROCESS9_CODE]@$[COMMON_1_OFFSET]:10 COMMON_1
fget $[PROCESS9_CODE]@$[COMMON_2_OFFSET]:10 COMMON_2
fget $[PROCESS9_CODE]@$[COMMON_3_OFFSET]:10 COMMON_3
fget $[PROCESS9_CODE]@$[COMMON_4_OFFSET]:10 COMMON_4
fget $[PROCESS9_CODE]@$[COMMON_5_OFFSET]:10 COMMON_5
imgumount
rm -o -s $[NATIVE_FIRM_DECRYPTED]
# NFC
if chk $[ONTYPE] "N3DS"
if not find 1:/title/00040130/20004002/content/????????.app NFC_APP
echo "New 3DS NFC not found."
goto Exit
end
set EXPECTED_NFC_VER "0700"
set NFC_PHRASE_0_OFFSET "355EE"
set NFC_SEED_0_OFFSET "355FC"
set NFC_HMAC_KEY_0_OFFSET "3560A"
set NFC_PHRASE_1_OFFSET "3561A"
set NFC_SEED_1_OFFSET "35628"
set NFC_HMAC_KEY_1_OFFSET "35638"
set NFC_IV_OFFSET "35648"
else
if not find 1:/title/00040130/00004002/content/????????.app NFC_APP
echo "Old 3DS NFC not found."
goto Exit
end
set EXPECTED_NFC_VER "0800"
set NFC_PHRASE_0_OFFSET "17382"
set NFC_SEED_0_OFFSET "17390"
set NFC_HMAC_KEY_0_OFFSET "1739E"
set NFC_PHRASE_1_OFFSET "173AE"
set NFC_SEED_1_OFFSET "173BC"
set NFC_HMAC_KEY_1_OFFSET "173CC"
set NFC_IV_OFFSET "173DC"
end
set NFC_EXTHEADER "G:/extheader.bin"
set NFC_CODE "$[GM9OUT]/nfc_code.bin"
imgmount $[NFC_APP]
fget $[NFC_EXTHEADER]@E:2 NFC_VER
if not chk $[NFC_VER] $[EXPECTED_NFC_VER]
echo "Unsupported NFC module version.\nThis script requires the latest 3DS firmware.\n\nExpected $[EXPECTED_NFC_VER], got $[NFC_VER]"
goto Exit
end
imgumount
extrcode $[NFC_APP] $[NFC_CODE]
fget $[NFC_CODE]@$[NFC_PHRASE_0_OFFSET]:E NFC_PHRASE_0
fget $[NFC_CODE]@$[NFC_SEED_0_OFFSET]:E NFC_SEED_0
fget $[NFC_CODE]@$[NFC_HMAC_KEY_0_OFFSET]:10 NFC_HMAC_KEY_0
fget $[NFC_CODE]@$[NFC_PHRASE_1_OFFSET]:E NFC_PHRASE_1
fget $[NFC_CODE]@$[NFC_SEED_1_OFFSET]:10 NFC_SEED_1
fget $[NFC_CODE]@$[NFC_HMAC_KEY_1_OFFSET]:10 NFC_HMAC_KEY_1
fget $[NFC_CODE]@$[NFC_IV_OFFSET]:10 NFC_IV
rm -o -s $[NFC_CODE]
# GodMode9 Key Database
set KEY_DB "V:/aeskeydb.bin"
set KEY_DB_18X "K:/slot0x18KeyX.ret.bin"
set KEY_DB_19X "K:/slot0x19KeyX.ret.bin"
set KEY_DB_1AX "K:/slot0x1AKeyX.ret.bin"
set KEY_DB_1BX "K:/slot0x1BKeyX.ret.bin"
set KEY_DB_1CX "K:/slot0x1CKeyX.ret.bin"
set KEY_DB_1DX "K:/slot0x1DKeyX.ret.bin"
set KEY_DB_1EX "K:/slot0x1EKeyX.ret.bin"
set KEY_DB_1FX "K:/slot0x1FKeyX.ret.bin"
set KEY_DB_25X "K:/slot0x25KeyX.ret.bin"
set KEY_DB_24Y "K:/slot0x24KeyY.bin"
set KEY_DB_2FY "K:/slot0x2FKeyY.ret.bin"
imgmount $[KEY_DB]
fget $[KEY_DB_18X]@0:10 KEYX_18
fget $[KEY_DB_19X]@0:10 KEYX_19
fget $[KEY_DB_1AX]@0:10 KEYX_1A
fget $[KEY_DB_1BX]@0:10 KEYX_1B
fget $[KEY_DB_1CX]@0:10 KEYX_1C
fget $[KEY_DB_1DX]@0:10 KEYX_1D
fget $[KEY_DB_1EX]@0:10 KEYX_1E
fget $[KEY_DB_1FX]@0:10 KEYX_1F
fget $[KEY_DB_25X]@0:10 KEYX_25
fget $[KEY_DB_24Y]@0:10 KEYY_24
fget $[KEY_DB_2FY]@0:10 KEYY_2F
imgumount
# Write Keys To File
set OUT "0:/gm9/aes_keys.txt"
dumptxt $[OUT] "# KeyX"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "slot0x18KeyX=$[KEYX_18]"
dumptxt -p $[OUT] "slot0x19KeyX=$[KEYX_19]"
dumptxt -p $[OUT] "slot0x1AKeyX=$[KEYX_1A]"
dumptxt -p $[OUT] "slot0x1BKeyX=$[KEYX_1B]"
dumptxt -p $[OUT] "slot0x1CKeyX=$[KEYX_1C]"
dumptxt -p $[OUT] "slot0x1DKeyX=$[KEYX_1D]"
dumptxt -p $[OUT] "slot0x1EKeyX=$[KEYX_1E]"
dumptxt -p $[OUT] "slot0x1FKeyX=$[KEYX_1F]"
dumptxt -p $[OUT] "slot0x25KeyX=$[KEYX_25]"
dumptxt -p $[OUT] "slot0x2CKeyX=$[KEYX_2C]"
dumptxt -p $[OUT] "slot0x2DKeyX=$[KEYX_2D]"
dumptxt -p $[OUT] "slot0x2EKeyX=$[KEYX_2E]"
dumptxt -p $[OUT] "slot0x2FKeyX=$[KEYX_2F]"
dumptxt -p $[OUT] "slot0x30KeyX=$[KEYX_30]"
dumptxt -p $[OUT] "slot0x31KeyX=$[KEYX_31]"
dumptxt -p $[OUT] "slot0x32KeyX=$[KEYX_32]"
dumptxt -p $[OUT] "slot0x33KeyX=$[KEYX_33]"
dumptxt -p $[OUT] "slot0x34KeyX=$[KEYX_34]"
dumptxt -p $[OUT] "slot0x35KeyX=$[KEYX_35]"
dumptxt -p $[OUT] "slot0x36KeyX=$[KEYX_36]"
dumptxt -p $[OUT] "slot0x37KeyX=$[KEYX_37]"
dumptxt -p $[OUT] "slot0x38KeyX=$[KEYX_38]"
dumptxt -p $[OUT] "slot0x39KeyX=$[KEYX_39]"
dumptxt -p $[OUT] "slot0x3AKeyX=$[KEYX_3A]"
dumptxt -p $[OUT] "slot0x3BKeyX=$[KEYX_3B]"
dumptxt -p $[OUT] "slot0x3CKeyX=$[KEYX_3C]"
dumptxt -p $[OUT] "slot0x3DKeyX=$[KEYX_3D]"
dumptxt -p $[OUT] "slot0x3EKeyX=$[KEYX_3E]"
dumptxt -p $[OUT] "slot0x3FKeyX=$[KEYX_3F]"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "# KeyY"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "slot0x04KeyY=$[KEYY_04]"
dumptxt -p $[OUT] "slot0x05KeyY=$[KEYY_05]"
dumptxt -p $[OUT] "slot0x06KeyY=$[KEYY_06]"
dumptxt -p $[OUT] "slot0x07KeyY=$[KEYY_07]"
dumptxt -p $[OUT] "slot0x08KeyY=$[KEYY_08]"
dumptxt -p $[OUT] "slot0x09KeyY=$[KEYY_09]"
dumptxt -p $[OUT] "slot0x0AKeyY=$[KEYY_0A]"
dumptxt -p $[OUT] "slot0x0BKeyY=$[KEYY_0B]"
dumptxt -p $[OUT] "slot0x24KeyY=$[KEYY_24]"
dumptxt -p $[OUT] "slot0x2EKeyY=$[KEYY_2E]"
dumptxt -p $[OUT] "slot0x2FKeyY=$[KEYY_2F]"
dumptxt -p $[OUT] "slot0x31KeyY=$[KEYY_31]"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "# DLP/NFC KeyY (slot 0x39)"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "dlpKeyY=$[KEYY_39_DLP]"
dumptxt -p $[OUT] "nfcKeyY=$[KEYY_39_NFC]"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "# Ticket Common KeyY (slot 0x3D)"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "common0=$[COMMON_0]"
dumptxt -p $[OUT] "common1=$[COMMON_1]"
dumptxt -p $[OUT] "common2=$[COMMON_2]"
dumptxt -p $[OUT] "common3=$[COMMON_3]"
dumptxt -p $[OUT] "common4=$[COMMON_4]"
dumptxt -p $[OUT] "common5=$[COMMON_5]"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "# KeyN"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "slot0x0DKeyN=$[KEYN_0D]"
dumptxt -p $[OUT] "slot0x2DKeyN=$[KEYN_2D]"
dumptxt -p $[OUT] "slot0x32KeyN=$[KEYN_32]"
dumptxt -p $[OUT] "slot0x36KeyN=$[KEYN_36]"
dumptxt -p $[OUT] "slot0x38KeyN=$[KEYN_38]"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "# NFC Secrets"
dumptxt -p $[OUT] ""
dumptxt -p $[OUT] "nfcSecret0Phrase=$[NFC_PHRASE_0]"
dumptxt -p $[OUT] "nfcSecret0Seed=$[NFC_SEED_0]"
dumptxt -p $[OUT] "nfcSecret0HmacKey=$[NFC_HMAC_KEY_0]"
dumptxt -p $[OUT] "nfcSecret1Phrase=$[NFC_PHRASE_1]"
dumptxt -p $[OUT] "nfcSecret1Seed=$[NFC_SEED_1]"
dumptxt -p $[OUT] "nfcSecret1HmacKey=$[NFC_HMAC_KEY_1]"
dumptxt -p $[OUT] "nfcIv=$[NFC_IV]"
@Exit

10
dist/dumpkeys/README.md vendored Normal file
View File

@ -0,0 +1,10 @@
# DumpKeys
This is a GodMode9 script that dumps all the keys and other related secrets that Citra needs from a real 3DS.
Usage:
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.
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" file off of your SD card into "(Citra directory)/sysdata/".

View File

@ -5,18 +5,26 @@ elseif(APPLE)
set(PLATFORM "mac")
elseif(UNIX)
set(PLATFORM "linux")
else()
message(FATAL_ERROR "Cannot build installer for this unsupported platform")
endif()
set(BUILD_DIR "${CMAKE_BINARY_DIR}/installer")
set(DIST_DIR "${BUILD_DIR}/dist")
set(TARGET_FILE "${DIST_DIR}/citra-setup-${PLATFORM}")
file(MAKE_DIRECTORY ${BUILD_DIR})
file(MAKE_DIRECTORY "${BUILD_DIR}" "${DIST_DIR}")
# 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.
# Calls the cmake command and runs a cmake file in "scripting" mode passing in variables with -D
add_custom_command(OUTPUT "${TARGET_FILE}"
COMMAND ${CMAKE_COMMAND} -DSRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D BUILD_DIR=${BUILD_DIR} -D TARGET_FILE=${TARGET_FILE} -P ${CMAKE_SOURCE_DIR}/CMakeModules/BuildInstaller.cmake
COMMAND ${CMAKE_COMMAND}
-DBASE_DIR=${CMAKE_SOURCE_DIR}
-DSRC_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-DBUILD_DIR=${BUILD_DIR}
-DTARGET_FILE=${TARGET_FILE}
-P ${CMAKE_SOURCE_DIR}/CMakeModules/BuildInstaller.cmake
WORKING_DIRECTORY ${BUILD_DIR}
)

View File

@ -1,9 +1,13 @@
[main]
host = https://www.transifex.com
[citra.emulator]
file_filter = <lang>.ts
source_file = en.ts
source_lang = en
type = QT
[main]
host = https://www.transifex.com
[o:citra:p:citra:r:emulator]
file_filter = <lang>.ts
source_file = en.ts
source_lang = en
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

4129
dist/languages/da_DK.ts vendored

File diff suppressed because it is too large Load Diff

4146
dist/languages/de.ts vendored

File diff suppressed because it is too large Load Diff

6940
dist/languages/el.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4098
dist/languages/es_ES.ts vendored

File diff suppressed because it is too large Load Diff

4194
dist/languages/fi.ts vendored

File diff suppressed because it is too large Load Diff

2297
dist/languages/fi_FI.ts vendored

File diff suppressed because it is too large Load Diff

4316
dist/languages/fr.ts vendored

File diff suppressed because it is too large Load Diff

6930
dist/languages/hu_HU.ts vendored Normal file

File diff suppressed because it is too large Load Diff

4125
dist/languages/id.ts vendored

File diff suppressed because it is too large Load Diff

4932
dist/languages/it.ts vendored

File diff suppressed because it is too large Load Diff

4211
dist/languages/ja_JP.ts vendored

File diff suppressed because it is too large Load Diff

4629
dist/languages/ko_KR.ts vendored

File diff suppressed because it is too large Load Diff

4121
dist/languages/lt_LT.ts vendored

File diff suppressed because it is too large Load Diff

4137
dist/languages/nb.ts vendored

File diff suppressed because it is too large Load Diff

4623
dist/languages/nl.ts vendored

File diff suppressed because it is too large Load Diff

4153
dist/languages/pl_PL.ts vendored

File diff suppressed because it is too large Load Diff

4209
dist/languages/pt_BR.ts vendored

File diff suppressed because it is too large Load Diff

4264
dist/languages/ro_RO.ts vendored

File diff suppressed because it is too large Load Diff

4951
dist/languages/ru_RU.ts vendored

File diff suppressed because it is too large Load Diff

4148
dist/languages/tr_TR.ts vendored

File diff suppressed because it is too large Load Diff

4233
dist/languages/vi_VN.ts vendored

File diff suppressed because it is too large Load Diff

4110
dist/languages/zh_CN.ts vendored

File diff suppressed because it is too large Load Diff

4151
dist/languages/zh_TW.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -13,6 +13,6 @@
<file alias="256x256/plus_folder.png">icons/256x256/plus_folder.png</file>
</qresource>
<qresource prefix="colorful">
<file>style.qss</file>
<file alias="style.qss">../default/style.qss</file>
</qresource>
</RCC>

View File

@ -1,4 +0,0 @@
/*
This file is intentionally left blank.
We do not want to apply any stylesheet for colorful, only icons.
*/

View File

@ -2,7 +2,13 @@
Name=colorful_dark
Comment=Colorful theme (Dark style)
Inherits=default
Directories=16x16
Directories=16x16,48x48,256x256
[16x16]
Size=16
[48x48]
Size=48
[256x256]
Size=256

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Some files were not shown because too many files have changed in this diff Show More