diff options
Diffstat (limited to 'pkgs/by-name/dx/dxvk/setup_dxvk.sh')
-rw-r--r-- | pkgs/by-name/dx/dxvk/setup_dxvk.sh | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/pkgs/by-name/dx/dxvk/setup_dxvk.sh b/pkgs/by-name/dx/dxvk/setup_dxvk.sh new file mode 100644 index 00000000000..4926acd3ba8 --- /dev/null +++ b/pkgs/by-name/dx/dxvk/setup_dxvk.sh @@ -0,0 +1,266 @@ +#!@bash@/bin/bash -e + +set -eu -o pipefail + +# shellcheck disable=SC2034 +{ + dxvk32_dir=@dxvk32@/bin + dxvk64_dir=@dxvk64@/bin + + mcfgthreads32_dir=@mcfgthreads32@/bin + mcfgthreads64_dir=@mcfgthreads64@/bin +} + +## Defaults + +declare -A dlls=( + [d3d9]="dxvk/d3d9.dll" + [d3d10]="dxvk/d3d10.dll dxvk/d3d10_1.dll dxvk/d3d10core.dll" + [d3d11]="dxvk/d3d11.dll" + [dxgi]="dxvk/dxgi.dll" + [mcfgthreads]="mcfgthreads/mcfgthread-12.dll" +) + +declare -A targets=([d3d9]=1 [d3d11]=1 [dxgi]=1 [mcfgthreads]=1) + +## Command-line Parsing + +usage() { + echo "DXVK @version@" + echo "Set up Wine prefix with DXVK DLLs" + echo + echo "USAGE" + echo " $0 [install|uninstall] [OPTIONS]" + echo + echo "COMMANDS" + echo " install Copy the DXVK DLLs into the prefix" + echo " uninstall Restore the backed up Wine DLLs in the prefix" + echo + echo "OPTIONS" + echo " --with(out)-dxgi Copy DXVK DXGI DLL into prefix (default: with DXGI)" + echo " --with(out)-d3d10 Copy D3D10 DLLs into prefix (default: without D3D10)" + echo " -s, --symlink Symlink instead of copy" + echo " -f, --force Create a Wine prefix even if it does not exist" + echo " -p, --prefix <PREFIX> Wine prefix to manage (default: \$WINEPREFIX)" + exit 1 +} + +case "${1:-}" in + uninstall|install) + action=$1 + shift + ;; + -h|--help) + usage + ;; + *) + if [ -n "${1:-}" ]; then + echo "Unrecognized command: $1" + fi + usage + ;; +esac + + +do_symlink=false +do_makeprefix=false + +while [ -n "${1:-}" ]; do + case "$1" in + --with-dxgi) + targets[dxgi]=1 + ;; + --without-dxgi) + unset "targets[dxgi]" + ;; + --with-d3d10) + targets[d3d10]=1 + ;; + --without-d3d10) + unset "targets[d3d10]" + ;; + -s|--symlink) + do_symlink=true + ;; + --no-symlink) + do_symlink=false + ;; + -f|--force) + do_makeprefix=true + ;; + --no-force) + do_makeprefix=false + ;; + -p|--prefix) + shift + if [ -n "${1:-}" ]; then + WINEPREFIX=$1 + else + echo "Required PREFIX missing" + usage + fi + ;; + -h|--help) + usage + ;; + *) + echo "Unrecognized option: $1" + usage + ;; + esac + shift +done + +## Get information on the Wine environment + +export WINEPREFIX=${WINEPREFIX:-"$HOME/.wine"} + +# check wine prefix before invoking wine, so that we +# don't accidentally create one if the user screws up +if ! $do_makeprefix && [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then + echo "$WINEPREFIX: Not a valid wine prefix." >&2 + exit 1 +fi + +export WINEDEBUG=-all +# disable mscoree and mshtml to avoid downloading +# wine gecko and mono +export WINEDLLOVERRIDES="mscoree,mshtml=" + +wine="wine" +wine64="wine64" +wineboot="wineboot" + +# $PATH is the way for user to control where wine is located (including custom Wine versions). +# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps. +# In such case, wine64 and winebooot will be present, but wine binary will be missing, +# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing. +wine_path=$(dirname "$(command -v $wineboot)") +wow64=true +if ! [ -f "$wine_path/$wine" ]; then + wine=$wine64 + wow64=false +fi + +# resolve 32-bit and 64-bit system32 path +winever=$($wine --version | grep wine) +if [ -z "$winever" ]; then + echo "$wine: Not a wine executable. Check your $wine." >&2 + exit 1 +fi + +# ensure wine placeholder dlls are recreated +# if they are missing +$wineboot -u + +win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null) +win64_sys_path="${win64_sys_path/$'\r'/}" +if $wow64; then + win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null) + win32_sys_path="${win32_sys_path/$'\r'/}" +fi + +if [ -z "${win32_sys_path:-}" ] && [ -z "${win64_sys_path:-}" ]; then + echo 'Failed to resolve C:\windows\system32.' >&2 + exit 1 +fi + +## Utility functions + +install_file() { + $do_symlink && file_cmd="ln -sv" || file_cmd="install -m 755 -v" + + srcfile=$1 + dstfile=$2 + + if [ -f "${srcfile}.so" ]; then + srcfile="${srcfile}.so" + fi + + if ! [ -f "${srcfile}" ]; then + echo "${srcfile}: File not found. Skipping." >&2 + return 1 + fi + + if [ -n "$1" ]; then + if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then + if ! [ -f "${dstfile}.old" ]; then + mv -v "${dstfile}" "${dstfile}.old" + else + rm -v "${dstfile}" + fi + fi + $file_cmd "${srcfile}" "${dstfile}" + else + echo "${dstfile}: File not found in wine prefix" >&2 + return 1 + fi +} + +uninstall_file() { + srcfile=$1 + dstfile=$2 + + if [ -f "${srcfile}.so" ]; then + srcfile="${srcfile}.so" + fi + + if ! [ -f "${srcfile}" ]; then + echo "${srcfile}: File not found. Skipping." >&2 + return 1 + fi + + if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then + echo "${dstfile}: File not found. Skipping." >&2 + return 1 + fi + + if [ -f "${dstfile}.old" ]; then + rm -v "${dstfile}" + mv -v "${dstfile}.old" "${dstfile}" + return 0 + else + return 1 + fi +} + +install_override() { + dll=$(basename "$1") + if ! $wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$dll" /d native /f >/dev/null 2>&1; then + echo -e "Failed to add override for $dll" + exit 1 + fi +} + +uninstall_override() { + dll=$(basename "$1") + if ! $wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v "$dll" /f > /dev/null 2>&1; then + echo "Failed to remove override for $dll" + fi +} + +## Perform the requested command + +declare -A paths + +for target in "${!targets[@]}"; do + [ "${targets[$target]}" -eq 1 ] || continue + for dll in ${dlls[$target]}; do + dllname=$(basename "$dll") + basedir=$(dirname "$dll") + + if [ -n "${win32_sys_path:-}" ]; then + basedir32=${basedir}32_dir + paths["${!basedir32}/$dllname"]="$win32_sys_path/$dllname" + fi + if [ -n "${win64_sys_path:-}" ]; then + basedir64=${basedir}64_dir + paths["${!basedir64}/$dllname"]="$win64_sys_path/$dllname" + fi + done +done + +for srcpath in "${!paths[@]}"; do + "${action}_file" "$srcpath" "${paths["$srcpath"]}" + "${action}_override" "$(basename "$srcpath" .dll)" +done |