[BACK]Return to fnaify CVS log [TXT][DIR] Up to [local] / projects / fnaify

Annotation of projects/fnaify/fnaify, Revision 1.209

1.115     thfr        1: #!/usr/bin/env ksh
1.1       thfr        2:
1.199     thfr        3: set -o errexit
                      4: set -o pipefail
1.198     thfr        5:
1.145     thfr        6: FNAIFY_VERSION=3.0
1.143     thfr        7:
1.75      thfr        8: #########################################################################
1.143     thfr        9: # fnaify                                                               #
                     10: # ======                                                               #
1.75      thfr       11: #                                                                      #
1.114     thfr       12: # Run FNA/XNA games on OpenBSD                                         #
1.75      thfr       13: #                                                                      #
1.190     thfr       14: # Copyright (c) 2017-2020 Thomas Frohwein                              #
1.75      thfr       15: # portability fixes by Mariusz Zaborski (oshogbo)                      #
                     16: #                                                                      #
                     17: # FNA is a reimplementation of the Microsoft XNA Game Studio 4.0       #
                     18: # Refresh libraries.                                                   #
                     19: # Thanks to the great work by Ethan Lee (flibitijibibo) games using FNA        #
                     20: # are highly portable and can even run on OpenBSD. Please refer to     #
                     21: # https://fna-xna.github.io/ for more information about FNA.           #
                     22: #                                                                      #
                     23: # License: ISC                                                         #
                     24: #########################################################################
                     25:
1.67      thfr       26: # TODO:
1.189     thfr       27: # - fix TODOs
1.116     thfr       28: # - fails to detect XNA in Streets of Fury EX because of whitespace; resolved after renaming .exe
1.120     thfr       29: # - update the creator for dllmap file; based on fnaify.dllmap.config
1.147     thfr       30: # - mention package fnaify-extralibs in documentation
1.153     thfr       31: # - add option to add runtime exe_flags to run mode
1.159     thfr       32: # - AVNT: find a way to have Steam deactivated for this one in libSteamworksNative.so
1.168     thfr       33: # - add flag to create log file (for fnaify, as well as the output from the game)
1.202     thfr       34: # - document '--' to end getopts parsing; can make it clear when to pass remaining args to game
1.207     thfr       35: # - add check for ffmpeg if needed
1.3       thfr       36:
1.144     thfr       37: USAGE="
                     38: Usage:
                     39:
1.194     thfr       40: $(basename "$0") [-i|-y] [-hsv] [-c configfile] [-D depdir] [-d gamedir] [-f frameworkfile | -F frameworkversion] [-m monopath] [userflags]
1.144     thfr       41:
1.190     thfr       42: -c: specify config file for dllmap
                     43: -D: add directory to native library loader
1.155     thfr       44: -d: game directory
1.190     thfr       45: -F: framework version
1.155     thfr       46: -f: framework file
1.144     thfr       47: -h: print usage information
                     48: -i: interactive mode
                     49: -m: add directories to MONO_PATH
1.191     thfr       50: -n: skip the library check
1.175     thfr       51: -s: force (re-)running setup
1.144     thfr       52: -y: non-interactive mode; automatically replies 'yes' to all recommended choices
1.142     thfr       53: -V: display version
1.144     thfr       54: -v: verbose output
                     55:
1.190     thfr       56: <userflags> are optional. These arguments are passed to the game runtime.
1.11      thfr       57: "
                     58:
1.106     thfr       59: depdir="/usr/local/lib:/usr/X11R6/lib" # /usr/X11R6/lib is location of libfreetype.so on OpenBSD
1.187     thfr       60: fnadir="/usr/local/share/FNA"
1.106     thfr       61: gamedir="$PWD"
                     62: interaction=n  # y|n|i: yes to all, no to all, interactive
1.155     thfr       63: debug=
1.106     thfr       64: licenses=
1.144     thfr       65: gameconfig=
1.175     thfr       66: force_setup=0
1.191     thfr       67: nolibcheck=0
1.153     thfr       68: frameworkfile=
1.189     thfr       69: setup_frameworkfile=
1.153     thfr       70: frameworkversion=
1.189     thfr       71: setup_frameworkversion=
1.153     thfr       72: frameworkmajor=
                     73: frameworkminor=
1.155     thfr       74: userflags=
1.142     thfr       75: monopath="${MONO_PATH}"
1.65      thfr       76: netstub_commit=e7d890e0ede0caa9e76ef37af6070344e3ab0abf
1.71      thfr       77: newline='
                     78: '
1.158     thfr       79: SAVEIFS=$IFS
                     80: exefile=
                     81: nexefile=0     # TODO: is nexefile really needed?
                     82: my_exe=""
                     83: exe_flags=""
                     84: exe_env=""
                     85: fna_warning=0
                     86: nlog_warning=0
1.202     thfr       87: set -A needlibarray    # array that will hold the names of needed libraries
1.199     thfr       88: FNAIFY_DEBUG=false
1.89      thfr       89:
1.84      thfr       90: if [ -d "/usr/local/lib/steamworks-nosteam" ] ; then
1.152     thfr       91:        monopath="${monopath}:/usr/local/lib/steamworks-nosteam"
1.89      thfr       92:        depdir="/usr/local/lib/steamworks-nosteam:$depdir"
1.96      thfr       93: fi
1.187     thfr       94: if [ -d "$fnadir" ] ; then
                     95:        monopath="${monopath}:${fnadir}"
                     96: fi
1.96      thfr       97: if [ -d "/usr/local/share/steamstubs" ]; then
1.142     thfr       98:        monopath="${monopath}:/usr/local/share/steamstubs"
1.84      thfr       99: fi
1.76      thfr      100: if [ -d "/usr/local/share/fnaify-libs" ]; then
                    101:        depdir="/usr/local/share/fnaify-libs:$depdir"
                    102: fi
                    103:
1.148     thfr      104: # array of lib names to ignore for the configuration checking
                    105: ignoredarray="
                    106: FarseerPhysics.Portable.xml
                    107: libCommunityExpressSW.so
                    108: libCSteamworks.so
                    109: libGalaxy64.so
                    110: libGalaxyCSharpGlue.so
                    111: libGalaxy.so
                    112: libParisSteam.so
                    113: libSkiaSharp.so
                    114: libSteamWrapper.so
                    115: libXNAFileDialog.so
                    116: libXNAWebRenderer.so
                    117: libsteam_api.so
                    118: libcef.so
                    119: libfmod.so
1.160     thfr      120: libfmodex.so
1.148     thfr      121: libfmodstudio.so
1.163     thfr      122: liblua53.so
1.148     thfr      123: libtiny_jpeg.so
                    124: steamwrapper.so
                    125: steam_appid.txt
                    126: "
                    127:
                    128: # array of mono files that need to be removed from the game folder
                    129: monofilearray="
1.163     thfr      130: CSteamworks.dll
1.148     thfr      131: I18N.CJK.dll
                    132: I18N.MidEast.dll
                    133: I18N.Other.dll
                    134: I18N.Rare.dll
                    135: I18N.West.dll
                    136: I18N.dll
                    137: Microsoft.CSharp.dll
                    138: Mono.CSharp.dll
                    139: Mono.Posix.dll
                    140: Mono.Security.dll
1.171     thfr      141: Steam.dll
1.148     thfr      142: System.Configuration.dll
1.159     thfr      143: System.Configuration.Install.dll
1.148     thfr      144: System.Core.dll
                    145: System.Data.dll
1.159     thfr      146: System.Design.dll
1.148     thfr      147: System.Drawing.dll
                    148: System.IO.Compression.FileSystem.dll
                    149: System.IO.Compression.dll
1.159     thfr      150: System.Management.dll
1.148     thfr      151: System.Net.dll
                    152: System.Numerics.dll
                    153: System.Runtime.Serialization.dll
                    154: System.Security.dll
                    155: System.ServiceModel.dll
1.159     thfr      156: System.Transactions.dll
1.148     thfr      157: System.Web.Extensions.dll
                    158: System.Web.Http.dll
                    159: System.Web.Services.dll
                    160: System.Web.dll
                    161: System.Windows.Forms.dll
                    162: System.Xml.Linq.dll
                    163: System.Xml.dll
                    164: System.dll
                    165: WindowsBase.dll
1.192     thfr      166: libMonoPosixHelper.so
1.148     thfr      167: libMonoPosixHelper.so.x86
                    168: libMonoPosixHelper.so.x86_64
1.192     thfr      169: libSteamworksNative.so
1.148     thfr      170: monoconfig
                    171: monomachineconfig
                    172: mscorlib.dll
                    173: "
                    174:
1.158     thfr      175: configbasearray="
1.168     thfr      176: BlitNet.dll
                    177: CDGEngine.dll
1.166     thfr      178: CommunityExpress.dll
                    179: FMOD.dll
1.158     thfr      180: FNA.dll
1.173     thfr      181: GameClasses.dll
1.158     thfr      182: MonoGame.Framework.dll
                    183: Nuclex.Input.dll
                    184: OpenAL-CS.dll
1.166     thfr      185: SDL2#.dll
                    186: SDL2-CS.dll
1.158     thfr      187: "
                    188:
1.136     thfr      189: debug_echo()
                    190: {
1.202     thfr      191:        [ "$FNAIFY_DEBUG" = "false" ] && return
1.136     thfr      192:        if [ "${1}" = '-n' ]; then
1.200     thfr      193:                printf '%b' "$2"
1.136     thfr      194:        else
1.200     thfr      195:                printf '%b\n' "$1"
1.136     thfr      196:        fi
                    197: }
                    198:
1.141     thfr      199: printdash()
                    200: {
1.194     thfr      201:        string=
                    202:        string="$*"
                    203:        if [ -z "$string" ]; then
1.141     thfr      204:                return
                    205:        fi
1.200     thfr      206:        printf '%b\n' "$string"
1.141     thfr      207:        c=1
                    208:        dashes=
1.194     thfr      209:        while [ $c -lt ${#string} ]
1.141     thfr      210:        do
                    211:                dashes="${dashes}-"
                    212:                # $((...)) for arithmetic substitution
                    213:                c=$((c+1))
                    214:        done
                    215:        echo "$dashes"
                    216: }
                    217:
1.149     thfr      218: inarray() # check if $1 is in array $2
                    219: {
                    220:        firstarg="$1"
                    221:        shift 1
1.201     thfr      222:        if echo "$*" | grep -q "$firstarg"
                    223:        then
                    224:                echo "true"
                    225:        else
                    226:                echo "false"
                    227:        fi
1.149     thfr      228: }
                    229:
                    230: # function to find the latest present library. Return -1 if none found.
                    231: # $1 is the basename of the library without the version suffix (e.g. /usr/lib/libc.so)
                    232: # it will return the filename of the latest library version (e.g. /usr/lib/libc.so.96.0)
1.141     thfr      233: latest_syslib()
                    234: {
1.149     thfr      235:        if [ -z "$1" ] ; then
1.141     thfr      236:                return 1
                    237:        fi
1.194     thfr      238:        find "$(dirname "$1")" -maxdepth 1 -name "$(basename "$1")*" | tail -1
1.141     thfr      239: }
                    240:
1.148     thfr      241: trunklibnam() # truncate library name
1.141     thfr      242: {
1.148     thfr      243:        libnam="$1"
                    244:        libnam="$(echo "$libnam" | sed -n -E "s/[\.0-9]*$//p")"
                    245:        echo "$libnam" | sed -E "s/(libSDL2[^-]*)-2\.0(\.so.*)/\1\2/"
1.141     thfr      246: }
                    247:
1.202     thfr      248: validlib() # returns "false" if $1 is in ignoredarray, otherwise "true"
1.149     thfr      249: {
1.194     thfr      250:        libnam="$(trunklibnam "$1")"
                    251:        if echo \""$ignoredarray"\" | grep -q "$libnam"; then
1.202     thfr      252:                echo "false"
1.194     thfr      253:        elif echo \""$libnam"\" | grep -q '\.dll[ \t]*'; then
1.202     thfr      254:                echo "false"
1.149     thfr      255:        else
1.202     thfr      256:                echo "true"
1.149     thfr      257:        fi
                    258: }
                    259:
                    260: symlink_mg_libs()
                    261: {
1.208     thfr      262:        set -A mg_subdirs x64 x86
1.149     thfr      263:        debug_echo "\nChecking for MonoGame x64/x86 dir to create symlinks"
                    264:
1.195     thfr      265:        if [ ! -e "$gamedir/x64" ] && [ ! -e "$gamedir/x86" ] ; then
1.205     thfr      266:                debug_echo "...Couldn't find directories x64 or x86 in $gamedir\n"
1.149     thfr      267:        else
1.195     thfr      268:                for d in "${mg_subdirs[@]}" ; do
1.149     thfr      269:                        debug_echo "\nProcessing library directory $gamedir/$d"
1.194     thfr      270:                        for file in $gamedir/$d; do
1.149     thfr      271:                                # sort out libs that need to be ignored
1.202     thfr      272:                                if [ "$(validlib "$file")" = "true" ]
                    273:                                then
1.149     thfr      274:                                        debug_echo "\tignored file: $file"
                    275:                                        continue
                    276:                                fi
                    277:                                debug_echo "\tfound library file: $file. Replacing with symlink..."
                    278:                                trunk=$(trunklibnam "$file")
                    279:                                rm "$gamedir/$d/$file"
                    280:                                debug_echo -n "\t\tchecking for location of $trunk... "
1.195     thfr      281:                                if [ -n "$(latest_syslib "/usr/local/lib/$trunk")" ] ; then
1.149     thfr      282:                                        debug_echo "found in /usr/local/lib!"
                    283:                                        trunkpath="/usr/local/lib/$trunk"
1.195     thfr      284:                                elif [ -n "$(latest_syslib "/usr/X11R6/lib/$trunk")" ] ; then
1.149     thfr      285:                                        debug_echo "found in /usr/X11R6/lib!"
                    286:                                        trunkpath="/usr/X11R6/lib/$trunk"
1.195     thfr      287:                                elif [ -n "$(latest_syslib "/usr/lib/$trunk")" ] ; then
1.149     thfr      288:                                        debug_echo "found in /usr/lib!"
                    289:                                        trunkpath="/usr/lib/$trunk"
                    290:                                else
                    291:                                        debug_echo "NOT FOUND!!"
                    292:                                        trunkpath=
1.196     thfr      293:                                        printf "\n\t - ERROR: couldn't find system lib for %s\n" "$file"
1.149     thfr      294:                                fi
                    295:                                ln -s "$(latest_syslib "$trunkpath")" "$gamedir/$d/$file"
                    296:                        done
                    297:                        debug_echo "Done with library directory $gamedir/$d"
                    298:                done
                    299:                debug_echo "\nCreating libdl.so.2 symlink\n"
1.163     thfr      300:                [ ! -e "$gamedir/libdl.so.2" ] && \
                    301:                        ln -s "$(latest_syslib /usr/lib/libc.so)" "$gamedir/libdl.so.2"
1.149     thfr      302:        fi
                    303: }
                    304:
1.144     thfr      305: selectexe()
1.136     thfr      306: {
1.206     thfr      307:        debug_echo "\nexecutable assembly selection routine"
1.156     thfr      308:        IFS="
                    309: "
1.206     thfr      310:        for xfile in $(cd "$gamedir" && find . -maxdepth 1 -type f -iname "*.exe" -exec basename {} \; | sort)
1.171     thfr      311:        do
1.195     thfr      312:                if      echo "$xfile" | ! grep -q vshost && \
                    313:                        echo "$xfile" | ! grep -iq config && \
                    314:                        echo "$xfile" | ! grep -q dotNetFx4 && \
                    315:                        echo "$xfile" | ! grep -q Updater
                    316:                then
1.170     thfr      317:                        exefile="$exefile$xfile:"
                    318:                        nexefile=$((nexefile + 1))
                    319:                fi
1.156     thfr      320:        done
                    321:        IFS=$SAVEIFS
1.136     thfr      322:        if [ $nexefile -gt 1 ]; then
1.196     thfr      323:                if [ "$interaction" = "y" ] ; then
1.189     thfr      324:                        # TODO: for now just pick the first .exe. Come up with
1.156     thfr      325:                        #        better heuristic
1.195     thfr      326:                        my_exe="$(echo "$exefile" | cut -f 1 -d ':')"
1.156     thfr      327:                else
1.136     thfr      328:                        i=1
                    329:                        while [ $i -le $nexefile ]; do
1.195     thfr      330:                                echo "$i: $(echo "$exefile" | cut -f $i -d ':')"
1.136     thfr      331:                                i=$((i + 1))
                    332:                        done
                    333:                        input_exe=0
1.196     thfr      334:                        while   [ ${#input_exe} -gt 2 ] \
1.206     thfr      335:                                || ! echo "$input_exe" | grep -q '[1-9]' \
1.196     thfr      336:                                || [ $input_exe -gt $((i - 1)) ]
                    337:                        do
1.143     thfr      338:                                echo -n "Enter number of .exe file to run: "
1.196     thfr      339:                                read -r input_exe
1.136     thfr      340:                        done
                    341:                        # NOTE: this only works for up to 9 candidate files
1.196     thfr      342:                        my_exe="$(echo "$exefile" | cut -f "$input_exe" -d ':')"
1.136     thfr      343:                fi
                    344:        elif [ $nexefile -eq 1 ]; then
                    345:                my_exe="$exefile"
                    346:        else
1.156     thfr      347:                # TODO: there appear to be games without .exe, like Streets of Rage 4
1.196     thfr      348:                printf "ERROR: no .exe file found\n\n"
1.136     thfr      349:                exit 1
                    350:        fi
                    351:        my_exe="$(echo "$my_exe" | sed -E "s/[ \t]$//")" # trim trailing whitespace
                    352: }
                    353:
1.144     thfr      354: check_gameconfig()
                    355: {
                    356:        if [ -z "$gameconfig" ] ; then
                    357:                if [ -f "$HOME/.config/fnaify/fnaify.dllmap.config" ] ; then
                    358:                        gameconfig="$HOME/.config/fnaify/fnaify.dllmap.config"
                    359:                        # check for outdated config file
1.196     thfr      360:                        if [ "$(grep -m 1 "fnaify version $FNAIFY_VERSION" "$gameconfig")" = "" ] ; then
                    361:                                echo "WARNING: $gameconfig appears to be out of date. It is strongly recommended to remove it and re-run $(basename "$0")."
1.144     thfr      362:                        fi
                    363:                else
1.187     thfr      364:                        if [ -f "$fnadir/FNA.dll.config" ] ; then
                    365:                                gameconfig="$fnadir/FNA.dll.config"
1.186     thfr      366:                        elif [ -f "/usr/local/share/fnaify/fnaify.dllmap.config" ] ; then
1.144     thfr      367:                                gameconfig="/usr/local/share/fnaify/fnaify.dllmap.config"
                    368:                        else    # in this case create ~/.config/fnaify/fnaify.dllmap.config
                    369:                                gameconfig="$HOME/.config/fnaify/fnaify.dllmap.config"
                    370:                                debug_echo "creating $gameconfig"
                    371:                                mkdir -p ~/.config/fnaify
                    372:                                cat <<EOF > "$gameconfig"
1.152     thfr      373: <!-- mono config file for fnaify -->
                    374: <!-- fnaify version 3.0 -->
                    375: <configuration>
                    376:        <dllmap dll="FAudio" target="libFAudio.so"/>
                    377:        <dllmap dll="MojoShader.dll" target="libmojoshader.so"/>
                    378:        <dllmap dll="SDL2.dll" target="libSDL2.so"/>
                    379:        <dllmap dll="SDL2_image.dll" target="libSDL2_image.so"/>
                    380:        <dllmap dll="SDL2_mixer.dll" target="libSDL2_mixer.so"/>
                    381:        <dllmap dll="SDL2_ttf.dll" target="libSDL2_ttf.so"/>
                    382:        <dllmap dll="freetype6" target="libfreetype.so" />
                    383:        <dllmap dll="freetype6.dll" target="libfreetype.so" />
                    384:        <dllmap dll="libtheorafile.dll" target="libtheorafile.so"/>
                    385:        <dllmap dll="libtheoraplay.dll" target="libtheoraplay.so"/>
                    386:        <dllmap dll="libvorbisfile.dll" target="libvorbisfile.so"/>
                    387:        <dllmap dll="libvorbisfile-3.dll" target="libvorbisfile.so"/>
                    388:        <dllmap dll="openal32.dll" target="libopenal.so"/>
                    389:        <dllmap dll="soft_oal.dll" target="libopenal.so"/>
                    390:        <dllmap dll="System.Native" target="libmono-native.so"/>
                    391:        <dllmap dll="System.Net.Security.Native" target="libmono-native.so"/>
1.183     thfr      392:        <dllmap dll="i:msvcrt" target="libc.so" os="!windows"/>
                    393:        <dllmap dll="i:msvcrt.dll" target="libc.so" os="!windows"/>
                    394:        <dllmap dll="msvcr100.dll" target="libc.so"/>
                    395:
                    396:        <dllmap dll="i:CommunityExpressSW" target="libcestub.so"/>
                    397:        <dllmap dll="i:CommunityExpressSW.dll" target="libcestub.so"/>
                    398:
                    399:        <dllmap dll="user32.dll">
                    400:                <dllentry dll="libc.so" name="GetWindowThreadProcessId" target="getthrid"/>
                    401:                <dllentry dll="libstubborn.so" name="SetWindowsHookEx" target="int_0"/>
                    402:                <dllentry dll="libstubborn.so" name="GetClipCursor" target="int_0"/>
                    403:                <dllentry dll="libstubborn.so" name="DestroyIcon" target="int_0"/>
                    404:        </dllmap>
1.152     thfr      405:
1.183     thfr      406:        <dllmap dll="ntdll.dll">
                    407:                <dllentry dll="libstubborn.so" name="NtQueryInformationProcess" target="int_0"/>
                    408:        </dllmap>
                    409:
                    410:        <dllmap dll="ArkSteamWrapper.dll">
                    411:                <dllentry dll="libstubborn.so" name="ArkSteamInit" target="int_0"/>
                    412:                <dllentry dll="libstubborn.so" name="ArkGetPlayerId" target="int_0"/>
                    413:        </dllmap>
                    414:
                    415:        <dllmap dll="CSteamworks">
                    416:                <dllentry dll="libstubborn.so" name="InitSafe" target="int_0"/>
                    417:                <dllentry dll="libstubborn.so" name="RestartAppIfNecessary" target="int_0"/>
                    418:        </dllmap>
                    419:
                    420:        <dllmap dll="discord-rpc">
                    421:                <dllentry dll="libstubborn.so" name="Initialize" target="int_0"/>
                    422:                <dllentry dll="libstubborn.so" name="Discord_Initialize" target="int_0"/>
                    423:                <dllentry dll="libstubborn.so" name="Discord_UpdatePresence" target="int_0"/>
                    424:                <dllentry dll="libstubborn.so" name="Discord_RunCallbacks" target="int_0"/>
                    425:        </dllmap>
                    426:
                    427:        <dllmap dll="BrutallyUnfairDll.dll">
                    428:                <dllentry dll="libstubborn.so" name="loadSteamDll" target="int_0"/>
                    429:                <dllentry dll="libstubborn.so" name="initSteamAPI" target="int_0"/>
                    430:                <dllentry dll="libstubborn.so" name="GetModuleHandle" target="int_0"/>
                    431:        </dllmap>
                    432:
                    433:        <dllmap dll="SteamworksNative">
                    434:                <dllentry dll="libstubborn.so" name="GetStat" target="int_0"/>
                    435:                <dllentry dll="libstubborn.so" name="Initialize" target="int_0"/>
                    436:                <dllentry dll="libstubborn.so" name="RunCallbacks" target="ptr_null"/>
                    437:                <dllentry dll="libstubborn.so" name="Services_RegisterManagedCallbacks" target="int_0"/>
                    438:        </dllmap>
                    439:
                    440:        <dllmap dll="steamwrapper.dll">
                    441:                <dllentry dll="libstubborn.so" name="API_RunCallbacks" target="int_0"/>
                    442:                <dllentry dll="libstubborn.so" name="API_Init" target="int_0"/>
                    443:                <dllentry dll="libstubborn.so" name="API_Shutdown" target="int_0"/>
                    444:                <dllentry dll="libstubborn.so" name="Stats_getStat" target="int_0"/>
                    445:                <dllentry dll="libstubborn.so" name="RestartViaSteamIfNecessary" target="int_0"/>
                    446:        </dllmap>
                    447:
                    448:        <dllmap dll="fmod_event.dll">
                    449:                <dllentry dll="libstubborn.so" name="FMOD_EventSystem_Create" target="int_0"/>
                    450:        </dllmap>
1.152     thfr      451:
                    452:        <dllmap dll="kernel32">
                    453:                <dllentry dll="ld.so" name="LoadLibrary" target="dlopen"/>
                    454:        </dllmap>
                    455:
                    456:        <!--<dllmap dll="SteamworksNative.dll" target="libSteamworksNative.so"/>-->
1.183     thfr      457:
1.152     thfr      458:        <dllmap dll="SteamWrapper.dll">
1.183     thfr      459:                <dllentry dll="libstubborn.so" name="SteamWrapper_GetCurrentGameLanguage" target="int_0"/>
                    460:                <dllentry dll="libstubborn.so" name="SteamWrapper_Init" target="int_0"/>
                    461:                <dllentry dll="libstubborn.so" name="SteamWrapper_GetUserDataFolder" target="string_empty"/>
                    462:                <dllentry dll="libstubborn.so" name="SteamWrapper_RunCallbacks"  target="int_0"/>
                    463:                <dllentry dll="libstubborn.so" name="SteamWrapper_LbUploadScore" target="int_0"/>
                    464:                <dllentry dll="libstubborn.so" name="SteamWrapper_Shutdown" target="int_0"/>
                    465:                <dllentry dll="libstubborn.so" name="SteamWrapper_SetAchievement" target="int_0"/>
1.152     thfr      466:        </dllmap>
1.183     thfr      467:
1.152     thfr      468:        <dllmap dll="steam_api">
1.183     thfr      469:                <dllentry dll="libstubborn.so" name="SteamAPI_Init" target="int_0"/>
                    470:                <dllentry dll="libstubborn.so" name="SteamAPI_RegisterCallback" target="int_0"/>
                    471:                <dllentry dll="libstubborn.so" name="SteamAPI_GetHSteamUser" target="int_0"/>
                    472:                <dllentry dll="libstubborn.so" name="SteamAPI_GetHSteamPipe" target="int_1"/>
                    473:                <dllentry dll="libstubborn.so" name="SteamInternal_CreateInterface" target="int_1"/>
                    474:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUser" target="int_1"/>
                    475:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamFriends" target="int_1"/>
                    476:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUtils" target="int_1"/>
                    477:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMatchmaking" target="int_1"/>
                    478:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMatchmakingServers" target="int_1"/>
                    479:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUserStats" target="int_1"/>
                    480:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamApps" target="int_1"/>
                    481:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamNetworking" target="int_1"/>
                    482:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamRemoteStorage" target="int_1"/>
                    483:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamScreenshots" target="int_1"/>
                    484:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamGameSearch" target="int_1"/>
                    485:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamHTTP" target="int_1"/>
                    486:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamController" target="int_1"/>
                    487:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUGC" target="int_1"/>
                    488:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamAppList" target="int_1"/>
                    489:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMusic" target="int_1"/>
                    490:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMusicRemote" target="int_1"/>
                    491:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamHTMLSurface" target="int_1"/>
                    492:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamInventory" target="int_1"/>
                    493:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamVideo" target="int_1"/>
                    494:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamParentalSettings" target="int_1"/>
                    495:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamInput" target="int_1"/>
                    496:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamParties" target="int_1"/>
                    497:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamUser_GetSteamID" target="int_1"/>
                    498:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamFriends_GetFriendPersonaName" target="string_empty"/>
                    499:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_RequestCurrentStats" target="int_1"/>
                    500:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_GetCurrentBetaName" target="string_empty"/>
                    501:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_BIsDlcInstalled" target="int_0"/>
                    502:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_GetLaunchCommandLine" target="string_empty"/>
                    503:                <dllentry dll="libstubborn.so" name="SteamUserStats" target="int_1"/>
                    504:                <dllentry dll="libstubborn.so" name="SteamRemoteStorage" target="int_1"/>
                    505:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamRemoteStorage_FileExists" target="int_0"/>
                    506:                <dllentry dll="libstubborn.so" name="SteamAPI_RunCallbacks" target="int_0"/>
                    507:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamRemoteStorage_FileWrite" target="int_0"/>
                    508:                <dllentry dll="libstubborn.so" name="SteamAPI_Shutdown" target="int_0"/>
                    509:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_GetAchievement" target="int_0"/>
                    510:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_SetAchievement" target="int_0"/>
                    511:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_StoreStats" target="int_0"/>
                    512:                <dllentry dll="libstubborn.so" name="SteamAPI_ISteamInput_Init" target="int_0"/>
                    513:                <dllentry dll="libstubborn.so" name="SteamAPI_RestartAppIfNecessary" target="int_0"/>
1.152     thfr      514:        </dllmap>
1.183     thfr      515:
1.152     thfr      516:        <dllmap dll="steam_api64">
1.183     thfr      517:                <dllentry dll="libstubborn.so" name="SteamAPI_Init" target="int_0"/>
1.152     thfr      518:        </dllmap>
                    519:
                    520:        <dllmap dll="fmodstudio">
1.183     thfr      521:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Create" target="int_0"/>
                    522:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Initialize" target="int_0"/>
                    523:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_SetListenerAttributes" target="int_0"/>
                    524:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Update" target="int_0"/>
                    525:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_LoadBankFile" target="int_0"/>
                    526:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetVCA" target="int_0"/>
                    527:                <dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_SetVolume" target="int_0"/>
                    528:                <dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_GetVolume" target="int_0"/>
                    529:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetEvent" target="int_0"/>
                    530:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_LoadSampleData" target="int_0"/>
                    531:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_CreateInstance" target="int_0"/>
                    532:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_Is3D" target="int_0"/>
                    533:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Start" target="int_0"/>
                    534:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetBus" target="int_0"/>
                    535:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_SetPaused" target="int_0"/>
                    536:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetPaused" target="int_0"/>
                    537:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetDescription" target="int_0"/>
                    538:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetPath" target="int_celeste_event"/>
                    539:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bank_LoadSampleData" target="int_0"/>
                    540:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetVolume" target="int_0"/>
                    541:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetListenerAttributes" target="int_0"/>
                    542:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Set3DAttributes" target="int_0"/>
                    543:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Release" target="int_0"/>
                    544:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetVolume" target="int_0"/>
                    545:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Stop" target="int_0"/>
                    546:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Get3DAttributes" target="int_0"/>
                    547:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Release" target="int_0"/>
                    548:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetParameterValue" target="int_0"/>
                    549:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_IsOneshot" target="int_0"/>
                    550:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetPaused" target="int_0"/>
                    551:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_TriggerCue" target="int_0"/>
                    552:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_StopAllEvents" target="int_0"/>
                    553:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPaused" target="int_0"/>
                    554:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPlaybackState" target="int_0"/>
                    555:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetLowLevelSystem" target="int_0"/>
                    556:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetInstanceCount" target="int_0"/>
                    557:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_UnloadSampleData" target="int_0"/>
                    558:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_FlushCommands" target="int_0"/>
                    559:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetChannelGroup" target="int_0"/>
                    560:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetCallback" target="int_0"/>
1.152     thfr      561:        </dllmap>
1.183     thfr      562:
1.152     thfr      563:        <dllmap dll="fmodstudio.dll">
1.183     thfr      564:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Create"  target="int_0"/>
                    565:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Initialize" target="int_0"/>
                    566:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_SetListenerAttributes" target="int_0"/>
                    567:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Update" target="int_0"/>
                    568:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_LoadBankFile" target="int_0"/>
                    569:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetVCA" target="int_0"/>
                    570:                <dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_SetVolume" target="int_0"/>
                    571:                <dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_GetVolume" target="int_0"/>
                    572:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetEvent" target="int_0"/>
                    573:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_LoadSampleData" target="int_0"/>
                    574:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_CreateInstance" target="int_0"/>
                    575:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_Is3D" target="int_0"/>
                    576:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Start" target="int_0"/>
                    577:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetBus" target="int_0"/>
                    578:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_SetPaused" target="int_0"/>
                    579:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetPaused" target="int_0"/>
                    580:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetDescription" target="int_0"/>
                    581:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetPath" target="int_celeste_event"/>
                    582:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bank_LoadSampleData" target="int_0"/>
                    583:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetVolume" target="int_0"/>
                    584:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetListenerAttributes" target="int_0"/>
                    585:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Set3DAttributes" target="int_0"/>
                    586:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Release" target="int_0"/>
                    587:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetVolume" target="int_0"/>
                    588:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Stop" target="int_0"/>
                    589:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Get3DAttributes" target="int_0"/>
                    590:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_Release" target="int_0"/>
                    591:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetParameterValue" target="int_0"/>
                    592:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_IsOneshot" target="int_0"/>
                    593:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetPaused" target="int_0"/>
                    594:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_TriggerCue" target="int_0"/>
                    595:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_StopAllEvents" target="int_0"/>
                    596:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPaused" target="int_0"/>
                    597:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPlaybackState" target="int_0"/>
                    598:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetLowLevelSystem" target="int_0"/>
                    599:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetInstanceCount" target="int_0"/>
                    600:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_UnloadSampleData" target="int_0"/>
                    601:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_LockChannelGroup" target="int_0"/>
                    602:                <dllentry dll="libstubborn.so" name="FMOD_Studio_System_FlushCommands" target="int_0"/>
                    603:                <dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetChannelGroup" target="int_0"/>
                    604:                <dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetCallback" target="int_0"/>
1.152     thfr      605:        </dllmap>
1.183     thfr      606:
1.152     thfr      607:        <dllmap dll="fmodex">
1.183     thfr      608:                <dllentry dll="libstubborn.so" name="FMOD_System_Create" target="int_0"/>
                    609:                <dllentry dll="libstubborn.so" name="FMOD_System_GetVersion" target="int_0"/>
                    610:                <dllentry dll="libstubborn.so" name="FMOD_System_Init" target="int_0"/>
                    611:                <dllentry dll="libstubborn.so" name="FMOD_System_SetReverbProperties" target="int_0"/>
                    612:                <dllentry dll="libstubborn.so" name="FMOD_System_Update" target="int_0"/>
1.152     thfr      613:        </dllmap>
                    614:
                    615:        <dllmap dll="uP2P.dll">
1.183     thfr      616:                <dllentry dll="libstubborn.so" name="libuP2P_liaison_init" target="int_1"/>
                    617:                <dllentry dll="libstubborn.so" name="libuP2P_hook" target="int_0"/>
                    618:                <dllentry dll="libstubborn.so" name="libuP2P_part_read" target="int_0"/>
                    619:                <dllentry dll="libstubborn.so" name="libuP2P_part" target="int_0"/>
                    620:                <dllentry dll="libstubborn.so" name="libuP2P_sync_zero" target="int_0"/>
                    621:                <dllentry dll="libstubborn.so" name="libuP2P_persona_rich" target="int_0"/>
                    622:                <dllentry dll="libstubborn.so" name="libuP2P_liaison_poll" target="int_0"/>
                    623:                <dllentry dll="libstubborn.so" name="libuP2P_fake" target="int_0"/>
                    624:                <dllentry dll="libstubborn.so" name="libuP2P_take" target="int_0"/>
                    625:                <dllentry dll="libstubborn.so" name="libuP2P_liaison_exit" target="int_0"/>
1.152     thfr      626:        </dllmap>
                    627:
                    628:        <dllmap dll="fmod">
1.183     thfr      629:                <dllentry dll="libstubborn.so" name="FMOD_System_GetVersion" target="int_fmf_getversion"/>
                    630:                <dllentry dll="libstubborn.so" name="FMOD_System_SetDSPBufferSize" target="int_0"/>
                    631:                <dllentry dll="libstubborn.so" name="FMOD_System_SetAdvancedSettings" target="int_0"/>
                    632:                <dllentry dll="libstubborn.so" name="FMOD_System_SetSoftwareChannels" target="int_0"/>
                    633:                <dllentry dll="libstubborn.so" name="FMOD_ChannelGroup_SetVolume" target="int_0"/>
                    634:                <dllentry dll="libstubborn.so" name="FMOD_ChannelGroup_SetPitch" target="int_0"/>
1.152     thfr      635:        </dllmap>
                    636:
                    637:        <!-- PhotonBridge: Unrailed! -->
                    638:        <dllmap dll="PhotonBridge">
1.183     thfr      639:                <dllentry dll="libstubborn.so" name="init" target="int_1"/>
                    640:                <dllentry dll="libstubborn.so" name="Init" target="int_1"/>
1.152     thfr      641:        </dllmap>
                    642:
1.183     thfr      643:        <dllmap dll="SteamLink.dll">
                    644:                <dllentry dll="libstubborn.so" name="SteamLink_Init" target="int_1"/>
                    645:                <dllentry dll="libstubborn.so" name="SteamLink_SetMessageCallbackPtr" target="int_0"/>
                    646:                <dllentry dll="libstubborn.so" name="SteamLink_SetDataReceivedCallbackPtr" target="int_0"/>
                    647:                <dllentry dll="libstubborn.so" name="SteamLink_SetPersonaStateChangeCallbackPtr" target="int_0"/>
                    648:                <dllentry dll="libstubborn.so" name="SteamLink_Shutdown" target="int_0"/>
                    649:                <dllentry dll="libstubborn.so" name="SteamLink_SetLobbyChatUpdateCallbackPtr" target="int_0"/>
                    650:                <dllentry dll="libstubborn.so" name="SteamLink_SetLobbyDataUpdatedCallbackPtr" target="int_0"/>
                    651:                <dllentry dll="libstubborn.so" name="SteamLink_SetLobbyCreatedCallbackPtr" target="int_0"/>
                    652:                <dllentry dll="libstubborn.so" name="SteamLink_SetLobbyEnteredCallbackPtr" target="int_0"/>
                    653:                <dllentry dll="libstubborn.so" name="SteamLink_SetLobbyGameCreatedCallbackPtr" target="int_0"/>
                    654:                <dllentry dll="libstubborn.so" name="SteamLink_SetBeginAuthResponseCallbackPtr" target="int_0"/>
                    655:                <dllentry dll="libstubborn.so" name="SteamLink_SetP2PSessionRequestCallbackPtr" target="int_0"/>
                    656:                <dllentry dll="libstubborn.so" name="SteamLink_SetP2PSessionConnectFailCallbackPtr" target="int_0"/>
                    657:                <dllentry dll="libstubborn.so" name="SteamLink_SetAvatarImageLoadedCallbackPtr" target="int_0"/>
                    658:                <dllentry dll="libstubborn.so" name="SteamLink_SetSteamServersConnectedCallbackPtr" target="int_0"/>
                    659:                <dllentry dll="libstubborn.so" name="SteamLink_SetSteamServersDisconnectedCallbackPtr" target="int_0"/>
                    660:                <dllentry dll="libstubborn.so" name="SteamLink_SetSteamServerConnectFailureCallbackPtr" target="int_0"/>
                    661:                <dllentry dll="libstubborn.so" name="SteamLink_SetServerListRefreshCompleteCallbackPtr" target="int_0"/>
                    662:                <dllentry dll="libstubborn.so" name="SteamLink_SetIPCFailureCallbackPtr" target="int_0"/>
                    663:                <dllentry dll="libstubborn.so" name="SteamLink_SetSteamShutdownCallbackPtr" target="int_0"/>
                    664:                <dllentry dll="libstubborn.so" name="SteamLink_SetUserStatsReceivedCallbackPtr" target="int_0"/>
                    665:                <dllentry dll="libstubborn.so" name="SteamLink_SetUserStatsStoredCallbackPtr" target="int_0"/>
                    666:                <dllentry dll="libstubborn.so" name="SteamLink_SetAchievementStoredCallbackPtr" target="int_0"/>
                    667:                <dllentry dll="libstubborn.so" name="SteamLink_SetPolicyResponseCallbackPtr" target="int_0"/>
                    668:                <dllentry dll="libstubborn.so" name="SteamLink_SetGSClientApproveCallbackPtr" target="int_0"/>
                    669:                <dllentry dll="libstubborn.so" name="SteamLink_SetGSClientDenyCallbackPtr" target="int_0"/>
                    670:                <dllentry dll="libstubborn.so" name="SteamLink_SetGSClientKickCallbackPtr" target="int_0"/>
                    671:                <dllentry dll="libstubborn.so" name="SteamLink_GetAchievementUnlockStatus" target="int_0"/>
                    672:        </dllmap>
1.152     thfr      673: </configuration>
                    674: EOF
1.144     thfr      675:                        fi
                    676:                fi
                    677:        fi
                    678: }
                    679:
1.13      thfr      680: libraryname()
                    681: {
                    682:         version="$1"
                    683:        if [ ! -e "$gamedir/$version" ]; then
1.205     thfr      684:                debug_echo "Couldn't find library directory $gamedir/$version"
1.13      thfr      685:        else
1.200     thfr      686:                debug_echo "\nEntering library directory $gamedir/$version"
1.208     thfr      687:                for file in "$gamedir"/"$version"/*; do
1.202     thfr      688:                        file="$(basename "$file")"
1.62      thfr      689:                        # sort out libs that need to be ignored
1.202     thfr      690:                        if [ "$(validlib "$file")" = "true" ]
                    691:                        then
1.28      thfr      692:                                debug_echo "\tignored file: $file"
1.13      thfr      693:                                continue
                    694:                        fi
1.199     thfr      695:                        debug_echo -n " found library file: $file"
1.13      thfr      696:                        file=$(trunklibnam "$file")
1.28      thfr      697:                        debug_echo -n " -> $file"
1.196     thfr      698:                        case "$(inarray "$file" "${needlibarray}")" in
1.201     thfr      699:                                "true")
1.196     thfr      700:                                        debug_echo " - already in array"
                    701:                                        ;;
1.201     thfr      702:                                "false")
1.202     thfr      703:                                        needlibarray[$((${#needlibarray[*]} + 1))]="$file"
1.196     thfr      704:                                        debug_echo ""
                    705:                                        ;;
                    706:                                *)
1.201     thfr      707:                                        printf "\n\tERROR: inarray returned with unexpected error\n\n"
1.196     thfr      708:                                        exit 1
                    709:                                        ;;
                    710:                        esac
1.13      thfr      711:                done
                    712:                debug_echo "Done with library directory $gamedir/$version"
                    713:        fi
                    714: }
                    715:
1.149     thfr      716: # install FNA into gamedir; specify version (e.g. 17.12) as $1
                    717: # if XNA bridge should be installed, add "xna_bridge" as $2
                    718: install_fna()
1.119     thfr      719: {
1.149     thfr      720:        if [ $# -lt 1 ]; then
                    721:                echo "ERROR: install_fna called with insufficient arguments"
                    722:                exit 1
                    723:        fi
                    724:        fna_version=
                    725:        if [ "${1}" = 'latest' ]; then
                    726:                # get version number of latest release from GitHub API
                    727:                fna_version=$(ftp -Vo - https://api.github.com/repos/FNA-XNA/FNA/releases/latest \
                    728:                        | grep -Eo "\"tag_name\"\:\"[0-9\.]*\"" \
                    729:                        | cut -d\" -f4)
1.119     thfr      730:        else
1.149     thfr      731:                fna_version="$1"
                    732:        fi
1.196     thfr      733:        printf '\nInstalling FNA %s ...' "${fna_version}\n"
1.149     thfr      734:        licenses="${licenses}FNA:\t\tMs-PL (https://github.com/FNA-XNA/FNA/blob/master/licenses/LICENSE)${newline}"
                    735:        lastdir="$PWD"
1.196     thfr      736:        cd /tmp || exit 1
                    737:        ftp -V "https://github.com/FNA-XNA/FNA/releases/download/${fna_version}/FNA-$(echo "$fna_version" | tr -d '.').zip"
1.65      thfr      738:        debug_echo "extracting FNA ${fna_version}"
1.196     thfr      739:        unzip "FNA-$(echo "$fna_version" | tr -d '.').zip" > /dev/null
                    740:        if      [ $# -gt 1 ] \
                    741:                && [ "$2" = "xna_bridge" ]
                    742:        then
                    743:                printf '\nInstalling FNA.NetStub for XNA ...\n'
1.74      thfr      744:                licenses="${licenses}FNA.NetStub:\tMs-PL (https://github.com/FNA-XNA/FNA.NetStub/blob/master/LICENSE)${newline}"
1.71      thfr      745:                ftp -V https://github.com/FNA-XNA/FNA.NetStub/archive/$netstub_commit.tar.gz
                    746:                tar zxf $netstub_commit.tar.gz
                    747:                mv FNA.NetStub-$netstub_commit FNA.NetStub
1.74      thfr      748:                echo -n "compiling XNA ABI/bridge files. This may take a moment... "
1.180     thfr      749:                xbuild /p:Configuration=Release FNA/abi/Microsoft.Xna.Framework.sln >> /tmp/fnaify-xbuild.log
1.73      thfr      750:                echo "done."
1.180     thfr      751:                cp /tmp/FNA/abi/bin/Release/* "$gamedir/"
1.65      thfr      752:        else
1.185     thfr      753:                # Download Vorbisfile-CS to be included in the build
                    754:                ftp https://raw.githubusercontent.com/flibitijibibo/Vorbisfile-CS/master/Vorbisfile.cs
                    755:                # add in FNA.Settings.props
                    756:                cat <<EOF > FNA/FNA.Settings.props
                    757: <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
                    758:        <ItemGroup>
                    759:                <Compile Include="lib/SDL2-CS/src/SDL2_image.cs" />
                    760:                <Compile Include="../Vorbisfile.cs" />
                    761:        </ItemGroup>
                    762: </Project>
                    763: EOF
1.74      thfr      764:                echo -n "compiling FNA ${fna_version} with xbuild... "
1.180     thfr      765:                xbuild /p:Configuration=Release FNA/FNA.sln >> /tmp/fnaify-xbuild.log
1.185     thfr      766:                echo "done."
1.65      thfr      767:                echo "Moving FNA.dll to fnaify-backup subdirectory"
                    768:                mkdir -p "$gamedir/fnaify-backup"
                    769:                mv "$gamedir/FNA.dll" "$gamedir/fnaify-backup/"
1.180     thfr      770:                cp /tmp/FNA/bin/Release/FNA.dll "$gamedir"
1.65      thfr      771:        fi
1.185     thfr      772:        debug_echo "removing the temporary build directories and returning to previous directory"
                    773:        rm -rf /tmp/FNA /tmp/FNA.NetStub /tmp/Vorbisfile.cs
1.196     thfr      774:        cd "$lastdir" || exit 1
1.65      thfr      775: }
1.13      thfr      776:
1.91      thfr      777: check_nlog()
                    778: {
                    779:        if [ -f "$gamedir/NLog.dll" ] ; then
1.196     thfr      780:                nlogversion=$(monodis --assembly "$gamedir/NLog.dll" | grep "Version" | tr -d '[:alpha:]' | tr -d " " | tr -d :)
                    781:                nlogmajor=$(echo "$nlogversion" | sed -n -E "s/\..*//p")
                    782:                nlogminor=$(echo "$nlogversion" | sed -n -E "s/[0-9]+\.([0-9]+)\.[0-9]+\.[0-9]+/\1/p")
1.91      thfr      783:                debug_echo -n "\tNLog.dll version $nlogversion, "
                    784:                debug_echo -n "major: $nlogmajor, "
                    785:                debug_echo "minor: $nlogminor"
1.196     thfr      786:                if      [ "$nlogmajor" -lt 4 ] \
                    787:                        && [ "$interaction" = "i" ]
                    788:                then
                    789:                        printf '\nInstall NLog 4.6.5 from www.nuget.org? [y/n] '
1.91      thfr      790:                        response=
1.196     thfr      791:                        until [ "$response" = "y" ] || [ "$response" = "n" ]
1.91      thfr      792:                        do
1.196     thfr      793:                                read -r response
1.91      thfr      794:                        done
1.196     thfr      795:                elif [ "$nlogmajor" -lt 4 ] && [ "$interaction" = "y" ] ; then
1.91      thfr      796:                        response="y"
                    797:                else
                    798:                        response="n"
                    799:                fi
1.196     thfr      800:                if [ "$response" = "y" ] ; then
1.91      thfr      801:                        debug_echo "Moving old NLog.dll out of the way"
                    802:                        mkdir -p "$gamedir/fnaify-backup"
                    803:                        mv "$gamedir/NLog.dll" "$gamedir/fnaify-backup/"
                    804:                        lastdir="$PWD"
                    805:                        mkdir /tmp/nlog
1.196     thfr      806:                        cd /tmp/nlog || exit 1
                    807:                        printf '\nInstalling NLog 4.6.5 ...\n'
1.91      thfr      808:                        licenses="${licenses}NLog:\tBSD 3-clause (https://github.com/NLog/NLog/blob/master/LICENSE.txt)${newline}"
                    809:                        ftp -Vo nlog.4.6.5.nupkg https://www.nuget.org/api/v2/package/NLog/4.6.5
                    810:                        unzip nlog.4.6.5.nupkg > /dev/null
                    811:                        cp lib/net45/NLog.dll "$gamedir/"
1.196     thfr      812:                        cd "$lastdir" || exit 1
1.100     thfr      813:                        rm -rf /tmp/nlog
1.196     thfr      814:                elif [ "$nlogmajor" -lt 4 ] ; then
1.98      thfr      815:                        nlog_warning=1
1.91      thfr      816:                fi
                    817:        fi
                    818: }
1.149     thfr      819:
                    820: process_options()
1.65      thfr      821: {
1.191     thfr      822:        while getopts c:Dd:F:f:hil:m:nsVvy o; do
1.149     thfr      823:                case "$o" in
1.152     thfr      824:                        c) gameconfig="$OPTARG" ;;
1.155     thfr      825:                        D) debug="--debug" ;;
                    826:                        d) gamedir=$(readlink -f "$OPTARG") ;;
                    827:                        f) frameworkfile="$OPTARG" ;;
                    828:                        F) frameworkversion="$OPTARG" ;;
1.149     thfr      829:                        h) echo "$USAGE"; exit 0;;
                    830:                        i) interaction=i ;;
1.155     thfr      831:                        l) depdir="$OPTARG" ;;
1.152     thfr      832:                        m) monopath="$OPTARG" ;;
1.191     thfr      833:                        n) nolibcheck=1 ;;
1.175     thfr      834:                        s) force_setup=1 ;;
1.149     thfr      835:                        V) echo "$FNAIFY_VERSION"; exit 0;;
1.199     thfr      836:                        v) FNAIFY_DEBUG=true ;;
1.149     thfr      837:                        y) interaction=y ;;
                    838:                        --) break ;;
1.196     thfr      839:                        *) ;;
1.149     thfr      840:                esac
1.65      thfr      841:        done
1.160     thfr      842:        debug_echo "options:    $*"
                    843:        debug_echo "OPTIND:     $OPTIND"
1.196     thfr      844:        shift $((OPTIND-1))
1.200     thfr      845:        debug_echo "options after shift:        $*\n"
1.196     thfr      846:        userflags=$*
1.65      thfr      847: }
1.152     thfr      848:
1.150     thfr      849: check_mono_binaries()
                    850: {
                    851:        debug_echo "Checking mono and monodis"
                    852:        if [ -z "$FNAIFY_MONO" ]; then
1.184     thfr      853:                FNAIFY_MONO="$(which mono 2>/dev/null)"
1.150     thfr      854:        fi
1.184     thfr      855:        [ -z "$FNAIFY_MONO" ] && { \
                    856:                echo "error finding mono"
                    857:                exit 1
                    858:        }
1.196     thfr      859:        if ! "$FNAIFY_MONO" --version 2>/dev/null >/dev/null
                    860:        then
1.150     thfr      861:                echo "error calling mono - aborting... Please make sure that mono is in path or set it in FNAIFY_MONO environment variable!"
                    862:                exit 1
                    863:        fi
                    864:        # check if monodis can be called
1.199     thfr      865:        if monodis 2>/dev/null
1.196     thfr      866:        then
1.150     thfr      867:                echo "error calling monodis - aborting... Please make sure that monodis is in the PATH!"
                    868:                exit 1
                    869:        fi
                    870: }
1.51      thfr      871:
1.123     thfr      872: iomap()
                    873: {
1.152     thfr      874:        debug_echo "iomap: checking if symlinks for filename cases need to be created"
1.196     thfr      875:        for f in $(find "$gamedir" -maxdepth 1 -name "*.exe" -exec basename {} \;); do
1.164     thfr      876:                case $f in
                    877:                        "Dead Pixels.exe" )
                    878:                                ln -sf Sprites Content/sprites
                    879:                                ln -sf Effects Content/Sprites/effects
                    880:                                ln -sf Splash Content/Sprites/splash
                    881:                                ln -sf Items Content/Sprites/InGame/items
                    882:                                ln -sf Grenades Content/Sprites/InGame/grenades
                    883:                                ln -sf Hud Content/Sprites/InGame/hud
                    884:                                ln -sf insideBuildings Content/Sprites/InGame/InsideBuildings
                    885:                                ln -sf Character Content/Sprites/InGame/character
                    886:                                ln -sf City Content/Sprites/InGame/city
                    887:                                ln -sf Traders Content/Sprites/InGame/traders
                    888:                                ln -sf Zombies Content/Sprites/InGame/zombies
                    889:                                ln -sf Objects Content/Sprites/InGame/objects
                    890:                                ln -sf Other Content/Sprites/InGame/other
                    891:                                ln -sf GunShots Content/Sprites/InGame/gunShots
                    892:                                ln -sf Buttons Content/Sprites/buttons
                    893:                                ln -sf Menu Content/Sprites/menu
                    894:                                ln -sf Cursor Content/Sprites/cursor
                    895:                                ln -sf Achievements Content/Sprites/achievements
                    896:                                ln -sf Credits Content/Sprites/credits
                    897:                                ln -sf Font Content/Sprites/font
                    898:                                ln -sf preview Content/Sprites/Preview
                    899:                                ln -sf preview Content/Sprites/Menu/Preview
                    900:                                ln -sf PsxButtons Content/Sprites/buttons/psxButtons
                    901:                                ln -sf Cutscene Content/Sprites/CutScene
                    902:                                ln -sf buildings Content/Sprites/InGame/City/Buildings
                    903:                                ln -sf mainbackground.xnb Content/ConfigSprites/mainBackground.xnb
                    904:                                ln -sf largeCuts.xnb Content/Sprites/effects/largecuts.xnb
                    905:                                ln -sf smallCuts.xnb Content/Sprites/effects/smallcuts.xnb
                    906:                                ln -sf effects Content/Sprites/Effects
                    907:                                ln -sf cuemark.xnb Content/Sprites/effects/cueMark.xnb
                    908:                                ln -sf Static.xnb Content/Sprites/Menu/Preview/static.xnb
                    909:                                ;;
                    910:                        AJ1.exe )
                    911:                                ln -sf j_rip.xnb Content/AJ1/j_Rip.xnb
                    912:                                ln -sf j_rip.xnb Content/AJ2/j_Rip.xnb
                    913:                                ln -sf Owlturnneo2.xnb Content/AJ1/owlturnneo2.xnb
                    914:                                ln -sf Owlturnneo2.xnb Content/AJ2/owlturnneo2.xnb
                    915:                                ;;
                    916:                        CSTW.exe )
                    917:                                ln -sf paws_Happy.xnb Content/Portrait/Paws/Paws_Happy.xnb
                    918:                                ;;
                    919:                        ThePit.exe )
                    920:                                ln -sf UI Content/ui
                    921:                                ;;
                    922:                        "Grand Class Melee.exe" )
                    923:                                ln -sf water.xnb Content/Sounds/Water.xnb
                    924:                                ln -sf grass.xnb Content/Sounds/Grass.xnb
                    925:                                ln -sf move.xnb Content/Sounds/Move.xnb
                    926:                                ln -sf select.xnb Content/Sounds/Select.xnb
                    927:                                ln -sf back.xnb Content/Sounds/Back.xnb
                    928:                                ln -sf squire_base.xnb Content/Textures/Players/Squire_base.xnb
                    929:                                ln -sf squire_greyscale.xnb Content/Textures/Players/Squire_greyscale.xnb
                    930:                                ln -sf militia_base.xnb Content/Textures/Players/Militia_base.xnb
                    931:                                ln -sf militia_greyscale.xnb Content/Textures/Players/Militia_greyscale.xnb
                    932:                                ln -sf apprentice_base.xnb Content/Textures/Players/Apprentice_base.xnb
                    933:                                ln -sf apprentice_greyscale.xnb Content/Textures/Players/Apprentice_greyscale.xnb
                    934:                                ln -sf savant_base.xnb Content/Textures/Players/Savant_base.xnb
                    935:                                ln -sf savant_greyscale.xnb Content/Textures/Players/Savant_greyscale.xnb
                    936:                                ln -sf sword.xnb Content/Textures/Weapons/Sword.xnb
                    937:                                ln -sf arrow.xnb Content/Sounds/Arrow.xnb
                    938:                                ln -sf scorch.xnb Content/Sounds/Scorch.xnb
                    939:                                ln -sf bigspeed.xnb Content/Sounds/Bigspeed.xnb
                    940:                                ln -sf frame_ingame_left_ruin.xnb Content/Textures/Menu/frame_ingame_left_Ruin.xnb
                    941:                                ln -sf frame_ingame_left_mire.xnb Content/Textures/Menu/frame_ingame_left_Mire.xnb
                    942:                                ln -sf frame_ingame_right_ruin.xnb Content/Textures/Menu/frame_ingame_right_Ruin.xnb
                    943:                                ln -sf frame_ingame_left_wood.xnb Content/Textures/Menu/frame_ingame_left_Wood.xnb
                    944:                                ln -sf ruin_leaf.xnb Content/Textures/Terrain/Ruin_leaf.xnb
                    945:                                ln -sf frame_ingame_right_wood.xnb Content/Textures/Menu/frame_ingame_right_Wood.xnb
                    946:                                ln -sf bigblow1.xnb Content/Sounds/Bigblow1.xnb
                    947:                                ln -sf ruin_grassmove.xnb Content/Textures/Terrain/Ruin_grassmove.xnb
                    948:                                ln -sf wood_leaf.xnb Content/Textures/Terrain/Wood_leaf.xnb
                    949:                                ln -sf ruin_watermove.xnb Content/Textures/Terrain/Ruin_watermove.xnb
                    950:                                ln -sf castshort.xnb Content/Sounds/Castshort.xnb
                    951:                                ln -sf frame_ingame_right_mire.xnb Content/Textures/Menu/frame_ingame_right_Mire.xnb
                    952:                                ln -sf frame_ingame_left_dune.xnb Content/Textures/Menu/frame_ingame_left_Dune.xnb
                    953:                                ln -sf sword1.xnb Content/Sounds/Sword1.xnb
1.168     thfr      954:                                ln -sf frame_ingame_right_dune.xnb Content/Textures/Menu/frame_ingame_right_Dune.xnb
                    955:                                ln -sf staff1.xnb Content/Sounds/Staff1.xnb
1.164     thfr      956:                                ;;
                    957:                        "LaserCat.exe" )
                    958:                                ln -sf audio Content/Audio
                    959:                                ;;
                    960:                        "MountYourFriends.exe" )
                    961:                                ln -sf menuBg.xnb Content/images/menubg.xnb
                    962:                                ln -sf humanClean.xnb Content/images/humanclean.xnb
                    963:                                ln -sf humanCleanNorm.xnb Content/images/humancleannorm.xnb
                    964:                                ln -sf menuMarker.xnb Content/images/menumarker.xnb
                    965:                                ln -sf stegersaurusLogo.xnb Content/images/backdrops/stegersauruslogo.xnb
                    966:                                ln -sf UIComponents.xnb Content/images/uicomponents.xnb
                    967:                                ln -sf restrictedArea.xnb Content/images/restrictedarea.xnb
                    968:                                ln -sf goatSheet.xnb Content/images/goatsheet.xnb
                    969:                                ln -sf BP3_SSTRIP_64.xnb Content/images/bp3_sstrip_64.xnb
                    970:                                ln -sf BP3_SSTRIP_32.xnb Content/images/bp3_sstrip_32.xnb
                    971:                                ln -sf keySheet.xnb Content/images/keysheet.xnb
                    972:                                ;;
                    973:                        "One Finger Death Punch.exe" )
                    974:                                ln -sf font2.xnb Content/Font2.xnb
                    975:                                ln -sf font5.xnb Content/Font5.xnb
                    976:                                ln -sf font6.xnb Content/Font6.xnb
                    977:                                ;;
                    978:                        "PhoenixForce.exe" )
                    979:                                ln -sf LIfeBar.xnb Content/1.4/Boss/lifeBar.xnb
                    980:                                ln -sf firewavexml.xml Content/1.4/Player/fireWavexml.xml
                    981:                                ln -sf firewave.xnb Content/1.4/Player/fireWave.xnb
                    982:                                ;;
                    983:                        "Streets of Fury EX.exe" )
                    984:                                ln -sf ShockWave.xnb Content/Texture2D/Shockwave.xnb
                    985:                                ;;
                    986:                        "Aces Wild.exe" )
                    987:                                ln -sf HitSparks Content/Sprites/Hitsparks
1.192     thfr      988:                                ln -sf preFabs.awx Content/Data/prefabs.awx
1.164     thfr      989:                                ;;
                    990:                        "CameraObscura.exe" )
                    991:                                ln -sf enemies Content/Enemies
                    992:                                ln -sf buttons Content/Buttons
                    993:                                ln -sf ui Content/UI
                    994:                                ln -sf particle Content/Particle
                    995:                                ;;
                    996:                        "DLC.exe" )
                    997:                                ln -sf ../../campaigns/dlcquest/texture/awardmentSpriteSheet.xnb Content/base/texture/awardmentSpriteSheet.xnb
                    998:                                ln -sf ../../campaigns/dlcquest/texture/dlcSpriteSheet.xnb Content/base/texture/dlcSpriteSheet.xnb
                    999:                                ln -sf ../../campaigns/dlcquest/data/map Content/base/data/map
                   1000:                                ln -sf ../../campaigns/dlcquest/texture/tiles_16x16.xnb Content/base/texture/tiles_16x16.xnb
                   1001:                                ln -sf ../../campaigns/dlcquest/texture/skyNightSpriteSheet.xnb Content/base/texture/skyNightSpriteSheet.xnb
                   1002:                                ln -sf ../../campaigns/dlcquest/texture/backgroundSpriteSheet.xnb Content/base/texture/backgroundSpriteSheet.xnb
                   1003:                                ln -sf ../../campaigns/dlcquest/texture/background2SpriteSheet.xnb Content/base/texture/background2SpriteSheet.xnb
                   1004:                                ln -sf ../../../campaigns/dlcquest/data/npc/shopkeep.xnb Content/base/data/npc/shopkeep.xnb
                   1005:                                ln -sf ../../../campaigns/dlcquest/data/npc/shopkeep2.xnb Content/base/data/npc/shopkeep2.xnb
                   1006:                                ln -sf ../../../campaigns/dlcquest/data/npc/shepherd.xnb Content/base/data/npc/shepherd.xnb
                   1007:                                ln -sf ../../../campaigns/dlcquest/data/npc/random.xnb Content/base/data/npc/random.xnb
                   1008:                                ln -sf ../../../campaigns/dlcquest/data/npc/filler.xnb Content/base/data/npc/filler.xnb
                   1009:                                ln -sf ../../../campaigns/dlcquest/data/npc/blacksmith.xnb Content/base/data/npc/blacksmith.xnb
                   1010:                                ln -sf ../../../campaigns/dlcquest/data/npc/sidequest.xnb Content/base/data/npc/sidequest.xnb
                   1011:                                ln -sf ../../../campaigns/dlcquest/data/npc/troll.xnb Content/base/data/npc/troll.xnb
                   1012:                                ln -sf ../../../campaigns/dlcquest/data/npc/gunsmith.xnb Content/base/data/npc/gunsmith.xnb
                   1013:                                ln -sf ../../../campaigns/dlcquest/data/npc/princess.xnb Content/base/data/npc/princess.xnb
                   1014:                                ln -sf ../../../campaigns/dlcquest/data/npc/horse.xnb Content/base/data/npc/horse.xnb
                   1015:                                ;;
1.166     thfr     1016:                        "EvilQuest.exe" )
1.167     thfr     1017:                                ln -sf Weapons Content/weapons
                   1018:                                ln -sf DialogWindow.xnb Content/HUD/dialogWindow.xnb
                   1019:                                ln -sf SpellSprites Content/spellSprites
                   1020:                                ln -sf PromptMessageWindow.xnb Content/HUD/promptMessageWindow.xnb
                   1021:                                ln -sf PromptWindow.xnb Content/HUD/promptWindow.xnb
                   1022:                                ln -sf Menu Content/menu
                   1023:                                ln -sf smallCursor.xnb Content/Menu/smallcursor.xnb
                   1024:                                ln -sf ItemIcons.xnb Content/Menu/itemIcons.xnb
                   1025:                                ln -sf SpellIcons.xnb Content/Menu/spellIcons.xnb
                   1026:                                ln -sf SplashSymbol.xnb Content/Menu/splashSymbol.xnb
                   1027:                                ln -sf SplashChaosoftLogo.xnb Content/Menu/splashChaosoftLogo.xnb
                   1028:                                ln -sf SplashGamesText.xnb Content/Menu/splashGamesText.xnb
                   1029:                                ln -sf PrisonGalvis_NoShadow.xnb Content/prisonGalvis_NoShadow.xnb
                   1030:                                ln -sf EnemySprites Content/enemysprites
                   1031:                                ln -sf Galvis_NoShadow.xnb Content/EnemySprites/galvis_noShadow.xnb
                   1032:                                ln -sf DemonGalvis.xnb Content/demonGalvis.xnb
                   1033:                                ln -sf StunnedEffect.xnb Content/SpellSprites/stunnedEffect.xnb
                   1034:                                ln -sf Colorize.xnb Content/colorize.xnb
                   1035:                                ln -sf bossDialogMusic.xnb Content/BossDialogMusic.xnb
                   1036:                                ln -sf Equip.xnb Content/Menu/equip.xnb
                   1037:                                ln -sf MessageWindow.xnb Content/Menu/messageWindow.xnb
                   1038:                                ln -sf Shop.xnb Content/shop.xnb
                   1039:                                ln -sf Title.xnb Content/Menu/title.xnb
                   1040:                                ln -sf TitleNewGame.xnb Content/Menu/titleNewGame.xnb
                   1041:                                ln -sf TitleNewGameActive.xnb Content/Menu/titleNewGameActive.xnb
                   1042:                                ln -sf GalvisTheme.xnb Content/galvisTheme.xnb
                   1043:                                ln -sf FlamesBG.xnb Content/Intro/Screen1/flamesBG.xnb
                   1044:                                ln -sf FlamesFG.xnb Content/Intro/Screen1/flamesFG.xnb
                   1045:                                ln -sf ForegroundMask.xnb Content/Intro/Screen1/foregroundMask.xnb
                   1046:                                ln -sf VillageBGFire.xnb Content/Intro/Screen3/villageBGFire.xnb
                   1047:                                ln -sf VillageFG.xnb Content/Intro/Screen3/villageFG.xnb
                   1048:                                ln -sf VillageFire.xnb Content/Intro/Screen3/villageFire.xnb
                   1049:                                ln -sf Galvis1.xnb Content/Intro/Screen3/galvis1.xnb
                   1050:                                ln -sf Galvis2.xnb Content/Intro/Screen3/galvis2.xnb
                   1051:                                ln -sf Silhouettes.xnb Content/Intro/Screen4/silhouettes.xnb
                   1052:                                ln -sf FullColor.xnb Content/Intro/Screen4/fullcolor.xnb
                   1053:                                ln -sf FlamesBG.xnb Content/Intro/Screen4/flamesBG.xnb
                   1054:                                ln -sf FlamesFG.xnb Content/Intro/Screen4/flamesFG.xnb
                   1055:                                ln -sf ForegroundMask.xnb Content/Intro/Screen4/foregroundMask.xnb
                   1056:                                ln -sf ArrestFG1.xnb Content/Intro/Screen5/arrestFG1.xnb
                   1057:                                ln -sf ArrestFG2.xnb Content/Intro/Screen5/arrestFG2.xnb
                   1058:                                ln -sf ArrestFG3.xnb Content/Intro/Screen5/arrestFG3.xnb
                   1059:                                ln -sf GalvisEndingCloseUpBG1.xnb Content/Intro/Screen9/GalvisEndingCloseupBG1.xnb
                   1060:                                ln -sf ControlsPC.xnb Content/Menu/controlsPC.xnb
                   1061:                                ln -sf amethyst.xnb Content/Amethyst.xnb
                   1062:                                ln -sf BattlefieldIntro.xnb Content/BATTLEFIELDINTRO.xnb
                   1063:                                ln -sf Prison2.xnb Content/PRISON2.xnb
                   1064:                                ln -sf Prison1.xnb Content/PRISON1.xnb
1.189     thfr     1065:                                ln -sf Items.xml Data/items.dat
                   1066:                                ln -sf NPCs.xml Data/NPCS.dat
1.166     thfr     1067:                                ;;
1.169     thfr     1068:                        "HELLYEAH.exe" )
                   1069:                                ln -sf QuadNoir.xnb Content/QUADNOIR.xnb
                   1070:                                ln -sf QuadBlanc.xnb Content/QUADBLANC.xnb
                   1071:                                ln -sf TRANS_Mask.xnb Content/TRANS_MASK.xnb
                   1072:                                ln -sf Popup Content/GAME/HUD/POPUP
                   1073:                                ln -sf pop_u_trung.xnb Content/GAME/HUD/Popup/POP_U_TRUNG.xnb
                   1074:                                ln -sf popup_cartouche_noir.xnb Content/GAME/HUD/Popup/POPUP_CARTOUCHE_NOIR.xnb
                   1075:                                ln -sf popup_barre_rouges.xnb Content/GAME/HUD/Popup/POPUP_BARRE_ROUGES.xnb
                   1076:                                ln -sf Menu_\(arial\).xnb Content/TITLE/FONTS/MENU_\(ARIAL\).xnb
                   1077:                                ln -sf cursor.xnb Content/PCONLY/CURSORS/CURSOR.xnb
                   1078:                                ln -sf viseur.xnb Content/PCONLY/CURSORS/VISEUR.xnb
                   1079:                                ln -sf Shaders Content/SHADERS
                   1080:                                ln -sf WhiteFlash.xnb Content/Shaders/WHITEFLASH.xnb
                   1081:                                ln -sf VaguePoison.xnb Content/Shaders/VAGUEPOISON.xnb
                   1082:                                ln -sf Black.xnb Content/Shaders/BLACK.xnb
                   1083:                                ln -sf White.xnb Content/Shaders/WHITE.xnb
                   1084:                                ln -sf BloomExtract.xnb Content/Shaders/BLOOMEXTRACT.xnb
                   1085:                                ln -sf BloomCombine.xnb Content/Shaders/BLOOMCOMBINE.xnb
                   1086:                                ln -sf GaussianBlur.xnb Content/Shaders/GAUSSIANBLUR.xnb
                   1087:                                ln -sf Sobel.xnb Content/Shaders/SOBEL.xnb
                   1088:                                ln -sf RadialBlur.xnb Content/Shaders/RADIALBLUR.xnb
                   1089:                                ln -sf VagueFeu.xnb Content/Shaders/VAGUEFEU.xnb
                   1090:                                ln -sf ColorEffects.xnb Content/Shaders/COLOREFFECTS.xnb
                   1091:                                ln -sf Explosion.xnb Content/Shaders/EXPLOSION.xnb
                   1092:                                ln -sf Ripple.xnb Content/Shaders/RIPPLE.xnb
                   1093:                                ln -sf RedFilter.xnb Content/Shaders/REDFILTER.xnb
                   1094:                                ln -sf Distortion.xnb Content/Shaders/DISTORTION.xnb
                   1095:                                ln -sf Lightning.xnb Content/Shaders/LIGHTNING.xnb
                   1096:                                ln -sf LoadingWheel.xnb Content/GAME/LOADING/LOADINGWHEEL.xnb
1.192     thfr     1097:                                ln -sf LOGO_Sega.xnb Content/LOGO/LOGO_SEGA.xnb
                   1098:                                ln -sf LOGO_Arkedo.xnb Content/LOGO/LOGO_ARKEDO.xnb
                   1099:                                ln -sf Sounds Content/GAME/WORLD/SOUNDS
                   1100:                                ln -sf HY_Sounds.xnb Content/GAME/WORLD/Sounds/HY_SOUNDS.xnb
                   1101:                                ln -sf picto_A.xnb Content/GAME/FONTS/PICTO/PICTO_A.xnb
                   1102:                                ln -sf picto_B.xnb Content/GAME/FONTS/PICTO/PICTO_B.xnb
                   1103:                                ln -sf picto_BK.xnb Content/GAME/FONTS/PICTO/PICTO_BK.xnb
                   1104:                                ln -sf picto_LB.xnb Content/GAME/FONTS/PICTO/PICTO_LB.xnb
                   1105:                                ln -sf picto_LS.xnb Content/GAME/FONTS/PICTO/PICTO_LS.xnb
                   1106:                                ln -sf picto_LT.xnb Content/GAME/FONTS/PICTO/PICTO_LT.xnb
                   1107:                                ln -sf picto_PAD.xnb Content/GAME/FONTS/PICTO/PICTO_PAD.xnb
                   1108:                                ln -sf picto_RB.xnb Content/GAME/FONTS/PICTO/PICTO_RB.xnb
                   1109:                                ln -sf picto_RS.xnb Content/GAME/FONTS/PICTO/PICTO_RS.xnb
                   1110:                                ln -sf picto_RT.xnb Content/GAME/FONTS/PICTO/PICTO_RT.xnb
                   1111:                                ln -sf picto_ST.xnb Content/GAME/FONTS/PICTO/PICTO_ST.xnb
                   1112:                                ln -sf picto_X.xnb Content/GAME/FONTS/PICTO/PICTO_X.xnb
                   1113:                                ln -sf picto_Y.xnb Content/GAME/FONTS/PICTO/PICTO_Y.xnb
                   1114:                                ln -sf picto_RS1.xnb Content/GAME/FONTS/PICTO/PICTO_RS1.xnb
                   1115:                                ln -sf picto_RS2.xnb Content/GAME/FONTS/PICTO/PICTO_RS2.xnb
                   1116:                                ln -sf picto_RS3.xnb Content/GAME/FONTS/PICTO/PICTO_RS3.xnb
                   1117:                                ln -sf picto_RS4.xnb Content/GAME/FONTS/PICTO/PICTO_RS4.xnb
                   1118:                                ln -sf picto_360.xnb Content/GAME/FONTS/PICTO/PICTO_360.xnb
                   1119:                                ln -sf saving.xnb Content/LOGO/SAVING.xnb
                   1120:                                ln -sf branchetonpad.xnb Content/PCONLY/MENUS/BRANCHETONPAD.xnb
                   1121:                                ln -sf pckey.xnb Content/PCONLY/MENUS/PCKEY.xnb
                   1122:                                ln -sf mousecenter.xnb Content/PCONLY/MENUS/MOUSECENTER.xnb
                   1123:                                ln -sf mousedefault.xnb Content/PCONLY/MENUS/MOUSEDEFAULT.xnb
                   1124:                                ln -sf mousedirections.xnb Content/PCONLY/MENUS/MOUSEDIRECTIONS.xnb
                   1125:                                ln -sf mouseleftbt.xnb Content/PCONLY/MENUS/MOUSELEFTBT.xnb
                   1126:                                ln -sf mouserightbt.xnb Content/PCONLY/MENUS/MOUSERIGHTBT.xnb
                   1127:                                ln -sf mousewheelup.xnb Content/PCONLY/MENUS/MOUSEWHEELUP.xnb
                   1128:                                ln -sf mousewheeldown.xnb Content/PCONLY/MENUS/MOUSEWHEELDOWN.xnb
                   1129:                                ln -sf ls.xnb Content/PCONLY/MENUS/LS.xnb
                   1130:                                ln -sf ls1.xnb Content/PCONLY/MENUS/LS1.xnb
                   1131:                                ln -sf ls2.xnb Content/PCONLY/MENUS/LS2.xnb
                   1132:                                ln -sf ls360.xnb Content/PCONLY/MENUS/LS360.xnb
                   1133:                                ln -sf rs1.xnb Content/PCONLY/MENUS/RS1.xnb
                   1134:                                ln -sf rs2.xnb Content/PCONLY/MENUS/RS2.xnb
                   1135:                                ln -sf rs3.xnb Content/PCONLY/MENUS/RS3.xnb
                   1136:                                ln -sf rs4.xnb Content/PCONLY/MENUS/RS4.xnb
                   1137:                                ln -sf "INT_Radar_(good_girl).xnb" "Content/GAME/FONTS/INT_RADAR_(GOOD_GIRL).xnb"
                   1138:                                ln -sf "DLG_Name_(trashand).xnb" "Content/GAME/FONTS/DLG_NAME_(TRASHAND).xnb"
                   1139:                                ln -sf Particules Content/TITLE/PARTICULES
                   1140:                                ln -sf boum.xnb Content/TITLE/Particules/BOUM.xnb
                   1141:                                ln -sf flameches.xnb Content/TITLE/Particules/FLAMECHES.xnb
                   1142:                                ln -sf fumee_background_flou.xnb Content/TITLE/Particules/FUMEE_BACKGROUND_FLOU.xnb
                   1143:                                ln -sf fumee_noire.xnb Content/TITLE/Particules/FUMEE_NOIRE.xnb
                   1144:                                ln -sf gaz_multicolor.xnb Content/TITLE/Particules/GAZ_MULTICOLOR.xnb
                   1145:                                ln -sf TITLE_Cartouche.xnb Content/TITLE/TITLE_CARTOUCHE.xnb
                   1146:                                ln -sf TITLE_Subtitle-EN.xnb Content/TITLE/TITLE_SUBTITLE-EN.xnb
                   1147:                                ln -sf TITLE_Logo.xnb Content/TITLE/TITLE_LOGO.xnb
                   1148:                                ln -sf TITLE_FlameScroll.xnb Content/TITLE/TITLE_FLAMESCROLL.xnb
                   1149:                                ln -sf TITLE_LogoMask.xnb Content/TITLE/TITLE_LOGOMASK.xnb
                   1150:                                ln -sf TITLE_Background.xnb Content/TITLE/TITLE_BACKGROUND.xnb
                   1151:                                ln -sf TITLE_Select.xnb Content/TITLE/TITLE_SELECT.xnb
1.169     thfr     1152:                                ;;
1.193     thfr     1153:                        "HonourRuns.exe" )
                   1154:                                ln -sf Sprites Content/sprites
                   1155:                                ln -sf Textures Content/textures
                   1156:                                ln -sf Levels Content/levels
                   1157:                                ;;
1.173     thfr     1158:                        "POOF.exe" )
                   1159:                                ln -sf QuadNoir.xnb Content/QUADNOIR.xnb
                   1160:                                ln -sf QuadBlanc.xnb Content/QUADBLANC.xnb
                   1161:                                ln -sf TRANS_Mask.xnb Content/TRANS_MASK.xnb
                   1162:                                ;;
1.189     thfr     1163:                        # beware, SSDD and SSDDXXL have the same named SSGame.exe
1.173     thfr     1164:                        "SSGame.exe" )
                   1165:                                # SSDDXXL
                   1166:                                ln -s HUD_ShopBackground.xnb Content/textures/menus/HUD_Shopbackground.xnb
                   1167:                                ln -s GLOBAL.xnb Content/levels/global.xnb
                   1168:                                ln -s HUD_challenge_skull.xnb Content/textures/menus/hud_challenge_skull.xnb
                   1169:                                ln -s LEVEL1.xnb Content/levels/level1.xnb
                   1170:                                # SSDD
                   1171:                                ln -s FRONT.xnb Content/levels/front.xnb
                   1172:                                ;;
                   1173:                        "TheFallOfGods2.exe" )
                   1174:                                ln -sf Data Content/data
                   1175:                                ;;
1.208     thfr     1176:                        "Snails.exe" )
                   1177:                                ln -s ScreensData.xnb Content/screens/screensdata.xnb
                   1178:                                ln -s footerMessage.xnb Content/fonts/footermessage.xnb
                   1179:                                ln -s MainMenu.xnb Content/screens/mainmenu.xnb
                   1180:                                ln -s UISnailsMenu.xnb Content/screens/controls/uisnailsmenu.xnb
                   1181:                                ln -s UIMainMenuBodyPanel.xnb Content/screens/controls/uimainmenubodypanel.xnb
1.164     thfr     1182:                esac
                   1183:        done
1.166     thfr     1184:        IFS=$SAVEIFS
1.128     thfr     1185: }
                   1186:
1.149     thfr     1187: xnasetup()
                   1188: {
1.188     thfr     1189:        if [ ! -d "$fnadir" ] ; then
1.196     thfr     1190:                if [ "$interaction" = "i" ] ; then
                   1191:                        printf '\nInstall FNA files from GitHub to for this XNA application? [y/n] '
1.188     thfr     1192:                        response=
1.196     thfr     1193:                        until [ "$response" = "y" ] || [ "$response" = "n" ]
1.188     thfr     1194:                        do
1.196     thfr     1195:                                read -r response
1.188     thfr     1196:                        done
1.196     thfr     1197:                elif [ "$interaction" = "y" ] ; then
1.188     thfr     1198:                        response="y"
                   1199:                else
                   1200:                        response="n"
                   1201:                fi
1.1       thfr     1202:
1.188     thfr     1203:                if [ "$response" = "y" ]; then
                   1204:                        install_fna latest xna_bridge
                   1205:                else
1.196     thfr     1206:                        printf 'Failed to install FNA/XNA files. Try running with -i or -y flag\n'
1.188     thfr     1207:                        exit 1
                   1208:                fi
1.149     thfr     1209:        fi
1.187     thfr     1210:
1.149     thfr     1211:        # convert .wma to .ogg and .wmv to .ogv
                   1212:        # https://gist.github.com/flibitijibibo/c97bc14aab04b1277d8ef5e97fc9aeff
                   1213:        IFS="
                   1214: "
1.189     thfr     1215:        # TODO: check for errors on return of these commands
1.160     thfr     1216:        echo "checking for WMA/WMV files and converting. This may take several minutes..."
1.149     thfr     1217:        for afile in $(find "$gamedir" -name "*.wma"); do
1.154     thfr     1218:                echo "converting $afile to OGG"
1.149     thfr     1219:                ffmpeg -loglevel fatal -i "$afile" -c:a libvorbis -q:a 10 \
                   1220:                        "$(echo "$afile" | rev | cut -d. -f2-$(($(echo "$afile" \
1.204     thfr     1221:                        | tr -dc '.' | wc -c) + 1)) | rev).ogg" \
                   1222:                        || echo "...skipping..."
1.149     thfr     1223:        done
                   1224:        for vfile in $(find . -name "*.wmv"); do
1.154     thfr     1225:                echo "converting $vfile to OGV"
1.149     thfr     1226:                ffmpeg -loglevel fatal -i "$vfile" -c:v libtheora -q:v 10 -c:a libvorbis \
                   1227:                        -q:a 10 "$(echo "$vfile" | rev | cut -d. -f2-$(($(echo "$vfile" \
1.204     thfr     1228:                        | tr -dc '.' | wc -c) + 1)) | rev).ogv" \
                   1229:                        || echo "...skipping..."
1.149     thfr     1230:        done
                   1231:        IFS=$SAVEIFS
                   1232:        echo " done."
                   1233: }
                   1234:
1.189     thfr     1235: get_setup_frameworkfile()
1.153     thfr     1236: {
1.189     thfr     1237:        if [ -e "$gamedir/FNA.dll" ] ; then
                   1238:                setup_frameworkfile="$gamedir/FNA.dll"
                   1239:        elif [ -e "$gamedir/MonoGame.Framework.dll" ] ; then
                   1240:                setup_frameworkfile="$gamedir/MonoGame.Framework.dll"
1.153     thfr     1241:        fi
                   1242: }
                   1243:
                   1244: get_frameworkversion()
                   1245: {
1.189     thfr     1246:        if [ -f "$1" ] ; then
1.196     thfr     1247:                monodis --assembly "$1" | grep -F Version | sed -E 's/Version:[[:blank:]]*//'
1.189     thfr     1248:        fi
1.181     thfr     1249: }
                   1250:
                   1251: get_frameworkmajor()
                   1252: {
                   1253:        echo "$1" | sed -n -E "s/([0-9]+)\.[0-9\.]+/\1/p"
                   1254: }
                   1255:
                   1256: get_frameworkminor()
                   1257: {
                   1258:        # strip leading zeros
                   1259:        echo "$1" | sed -n -E "s/[0-9]+\.([0-9]+).*/\1/p" | sed "s/^0*//"
1.153     thfr     1260: }
                   1261:
1.162     thfr     1262: check_eagle_island()
                   1263: {
1.196     thfr     1264:        { [ -f "$gamedir/EagleIsland.exe" ] && \
                   1265:        [ "$(basename "$gamedir")" != "Linux" ]; } && \
1.162     thfr     1266:        { \
                   1267:                debug_echo "correct gamedir for Eagle Island"
                   1268:                gamedir="${gamedir}/Linux"
                   1269:        }
                   1270: }
                   1271:
1.149     thfr     1272: run()
                   1273: {
1.162     thfr     1274:        check_eagle_island
1.179     thfr     1275:        [ -e "$gamedir/.fnaify_ready" ] || { echo "ERROR: setup not completed."; exit 1; }
1.150     thfr     1276:        check_mono_binaries
1.196     thfr     1277:        cd "$gamedir" || exit 1
1.149     thfr     1278:
                   1279:        selectexe
1.158     thfr     1280:        check_gameconfig
1.196     thfr     1281:        [ -e "$gameconfig" ] || { echo "ERROR: provided gameconfig file not existent: $gameconfig"; exit 1; }
1.158     thfr     1282:        debug_echo "gameconfig: $gameconfig"
1.172     thfr     1283:
                   1284:        # Quirks
                   1285:        my_exe="$(echo "$my_exe" | tr -d '\:')"
                   1286:        case "$my_exe" in
1.209   ! thfr     1287:                Blueberry.exe|Shenzhen.exe|ThePit.exe )
1.172     thfr     1288:                        exe_env="${exe_env}MONO_FORCE_COMPAT=1 "
                   1289:                        ;;
                   1290:                Hacknet.exe )
                   1291:                        exe_flags="${exe_flags}-disableweb "
                   1292:                        ;;
                   1293:                ScourgeBringer.exe )
                   1294:                        exe_flags="${exe_flags}-noSound "
                   1295:                        ;;
                   1296:                MidBoss.exe )
1.196     thfr     1297:                        if      [ -e fnaify.dllmap.MidBoss.config ] &&
                   1298:                                [ "$(diff -U 0 "$gameconfig" fnaify.dllmap.MidBoss.config | \
1.172     thfr     1299:                                        wc -l)" -eq 5 ]
1.196     thfr     1300:                        then
1.172     thfr     1301:                                debug_echo "fnaify.dllmap.MidBoss.config up to date."
                   1302:                        else
                   1303:                                debug_echo "fnaify.dllmap.MidBoss.config is missing or out of date."
                   1304:                                debug_echo "creating fnaify.dllmap.MidBoss.config from $gameconfig for MidBoss"
                   1305:                                # copy $gameconfig to fnaify.dllmap.MidBoss.config
                   1306:                                cp "$gameconfig" fnaify.dllmap.MidBoss.config
                   1307:                                # edit fnaify.dllmap.MidBoss.config to use libSDL2_image_compact.so
                   1308:                                sed -Ei 's/libSDL2_image\.so/libSDL2_image_compact.so/g' \
                   1309:                                        fnaify.dllmap.MidBoss.config
                   1310:                                # redefine gameconfig to fnaify.dllmap.MidBoss.config
                   1311:                                gameconfig=fnaify.dllmap.MidBoss.config
                   1312:                        fi
                   1313:                        ;;
1.188     thfr     1314:                SSGame.exe )
                   1315:                        mkdir -p ~/.local/share/SSDD
                   1316:                        ;;
1.172     thfr     1317:        esac
                   1318:
1.158     thfr     1319:        for f in $configbasearray; do
                   1320:                [ -e "$f" ] && { \
1.160     thfr     1321:                        debug_echo "existing symlink target: ${f}.config -> $(readlink "${f}.config")"
1.158     thfr     1322:                        gameconfigsymlink="${gameconfigsymlink}${f}.config "
1.196     thfr     1323:                        [ "$gameconfig" = "$(readlink "${f}.config")" ] \
1.181     thfr     1324:                                || ln -sf "$gameconfig" "${f}.config"
1.158     thfr     1325:                }
                   1326:        done
1.160     thfr     1327:        gameconfigsymlink="${gameconfigsymlink}${my_exe}.config "
1.196     thfr     1328:        [ "$gameconfig" = "$(readlink "${my_exe}.config")" ] || \
1.160     thfr     1329:                ln -sf "$gameconfig" "${my_exe}.config"
                   1330:
1.149     thfr     1331:        # format all relevant command variables
                   1332:        depdir="$(echo "$depdir" | sed -E 's/:$//')"
                   1333:        monopath="$(echo "$monopath" | sed -E 's/:$//' | sed -E 's/^://')"
1.189     thfr     1334:
                   1335:        #########################################
                   1336:        # Heuristic for frameworkfile selection #
                   1337:        #########################################
                   1338:
                   1339:        # Scenario: user-specified framework file (-f)
                   1340:        if [ -n "$frameworkfile" ] ; then
                   1341:                debug_echo "using user-supplied frameworkfile: $frameworkfile"
                   1342:
                   1343:        # Scenario: MonoGame.Framework.dll
                   1344:        elif [ -f "$gamedir/MonoGame.Framework.dll" ] ; then
                   1345:                frameworkfile="$gamedir/MonoGame.Framework.dll"
                   1346:
                   1347:        # Scenario: user-specified framework version (-F)
                   1348:        elif [ -n "$frameworkversion" ] ; then
                   1349:                # check fnadir and gamedir for fitting version
                   1350:                if [ -f "$fnadir/FNA.dll" ] ; then
                   1351:                        file_fwv="$(get_frameworkversion "$fnadir/FNA.dll")"
                   1352:                        if [ "$(get_frameworkmajor "$file_fwv").$(get_frameworkminor "$file_fwv")" = "$(get_frameworkmajor "$frameworkversion").$(get_frameworkminor "$frameworkversion")" ] ; then
                   1353:                                frameworkfile="$fnadir/FNA.dll"
                   1354:                        fi
                   1355:                fi
1.196     thfr     1356:                if [ -z "$frameworkfile" ] && [ -f "$gamedir/FNA.dll" ] ; then
1.189     thfr     1357:                        file_fwv="$(get_frameworkversion "$gamedir/FNA.dll")"
                   1358:                        if [ "$(get_frameworkmajor "$file_fwv").$(get_frameworkminor "$file_fwv")" = "$(get_frameworkmajor "$frameworkversion").$(get_frameworkminor "$frameworkversion")" ] ; then
                   1359:                                frameworkfile="$gamedir/FNA.dll"
                   1360:                        fi
                   1361:                fi
                   1362:                if [ -z "$frameworkfile" ] ; then
1.196     thfr     1363:                        install_fna "$frameworkversion"
1.189     thfr     1364:                        frameworkfile="$gamedir/FNA.dll"
1.188     thfr     1365:                fi
1.181     thfr     1366:
1.189     thfr     1367:        # Scenario: no frameworkfile in gamedir
                   1368:        elif [ ! -f "$gamedir/FNA.dll" ] ; then
                   1369:                if [ -e "$gamedir/.fnaify_needfna" ] ; then
                   1370:                        # this occurs if fnaify uses system framework file
                   1371:                        if [ -f "$fnadir/FNA.dll" ] ; then
                   1372:                                frameworkfile="$fnadir/FNA.dll"
                   1373:                        else
                   1374:                                echo "ERROR: frameworkfile needed, but not found. Try re-installing?"
                   1375:                                exit
                   1376:                        fi
                   1377:                else
                   1378:                        debug_echo "game without framework file"
1.182     thfr     1379:                fi
1.189     thfr     1380:
                   1381:        # Scenario: FNA.dll in fnadir
                   1382:        elif [ -f "$fnadir/FNA.dll" ] ; then
                   1383:                # existence of $gamedir/FNA.dll is implied by above elif [ ! -f $gamedir/FNA.dll ]
                   1384:                debug_echo "by default, move FNA.dll out of gamedir if present in fnadir"
                   1385:                mkdir -p "$gamedir/fnaify-backup"
                   1386:                mv "$gamedir/FNA.dll" "$gamedir/fnaify-backup/"
                   1387:                debug_echo "touch .fnaify_needfna to make it clear framework file is needed"
                   1388:                touch "$gamedir/.fnaify_needfna"
                   1389:                frameworkfile="$fnadir/FNA.dll"
                   1390:
                   1391:        # Scenario: FNA.dll in gamedir - suboptimal for compatibility since mojoshader updates
1.182     thfr     1392:        else
1.189     thfr     1393:                # existence of $gamedir/FNA.dll implied by above
                   1394:                frameworkfile="$gamedir/FNA.dll"
1.181     thfr     1395:        fi
1.187     thfr     1396:
1.189     thfr     1397:        if [ -z "$frameworkversion" ] ; then
                   1398:                frameworkversion="$(get_frameworkversion "$frameworkfile")"
                   1399:        fi
1.181     thfr     1400:
1.158     thfr     1401:        datasize=$(( $(ulimit -d) / 1024 ))
1.149     thfr     1402:
1.152     thfr     1403:        echo
1.149     thfr     1404:        printdash "fnaify runtime configuration"
1.171     thfr     1405:        echo "fnaify Version:                   $FNAIFY_VERSION"
1.149     thfr     1406:        echo "Game Directory:                   $PWD"           # PWD as cd'd into $gamedir happened above
                   1407:        echo "Mono Binary:                      $FNAIFY_MONO"
                   1408:        echo "Mono Path:                        $monopath"
1.163     thfr     1409:        echo "Main Assembly:                    $my_exe"
1.149     thfr     1410:        echo "Native Library Directories:       $depdir"
                   1411:        echo "Framework File:                   $frameworkfile"
1.153     thfr     1412:        echo "Framework File Version:           $frameworkversion"
1.158     thfr     1413:        echo "Symlinks to Config:               $gameconfigsymlink"
1.149     thfr     1414:        echo "Config File:                      $gameconfig"
1.153     thfr     1415:        echo "Other Runtime Environment:        $exe_env"
1.160     thfr     1416:        echo "Runtime Flags:                    $exe_flags $userflags"
1.159     thfr     1417:        echo "Datasize Limit:                   ${datasize} M"
1.160     thfr     1418:        echo
1.149     thfr     1419:
1.158     thfr     1420:        [ $datasize -lt 2048 ] && { \
                   1421:                echo "AT LEAST 2G are recommended for most games. See ksh(1) for ulimit command documentation"
                   1422:                echo
                   1423:        }
1.149     thfr     1424:
1.153     thfr     1425:        # check if broken symlinks exist in the game directory, e.g. libdl.so.2
1.160     thfr     1426:        IFS='
                   1427: '
1.149     thfr     1428:        for l in $(find . -type l); do
1.160     thfr     1429:                IFS=$SAVEIFS
1.149     thfr     1430:                if [ ! -e "$l" ] ; then
1.196     thfr     1431:                        newl="$(latest_syslib "$(trunklibnam "$(readlink "$l")")")"
1.149     thfr     1432:                        if [ -z "$newl" ] ; then
                   1433:                                echo "ERROR - broken symlink: $l. Expect trouble."
                   1434:                        else
                   1435:                                ln -fs "$newl" "$l"
                   1436:                        fi
                   1437:                fi
                   1438:        done
                   1439:
1.196     thfr     1440:        debug_echo "env LD_LIBRARY_PATH=\"$depdir\" MONO_PATH=\"$monopath\" $exe_env \"$FNAIFY_MONO\" $debug \"$my_exe\" $exe_flags $userflags"
1.161     thfr     1441:        debug_echo ""
1.199     thfr     1442:        env LD_LIBRARY_PATH="$depdir" MONO_PATH="$monopath" $exe_env "$FNAIFY_MONO" $debug "$my_exe" $exe_flags $userflags
1.149     thfr     1443:
1.151     thfr     1444:        exit 0
1.149     thfr     1445: }
                   1446:
                   1447: setup()
                   1448: {
1.177     thfr     1449:        echo "Performing setup (mode: $interaction) ..."
1.150     thfr     1450:        check_mono_binaries
1.162     thfr     1451:        check_eagle_island
                   1452:
1.196     thfr     1453:        cd "$gamedir" || exit 1
1.149     thfr     1454:        debug_echo "gamedir: $PWD"      # cd'd into direct above
                   1455:
1.155     thfr     1456:        debug_echo "Setting up the framework files"
1.189     thfr     1457:        get_setup_frameworkfile
1.203     thfr     1458:        if [ -z "$setup_frameworkfile" ]; then
                   1459:                debug_echo "... no framework file found. Checking other options..."
                   1460:        else
                   1461:                debug_echo "    framework file:                 $setup_frameworkfile"
                   1462:                setup_frameworkversion="$(get_frameworkversion "$setup_frameworkfile")"
                   1463:                debug_echo "    framework version:      $setup_frameworkversion"
                   1464:        fi
1.153     thfr     1465:
1.189     thfr     1466:        if [ -z "$setup_frameworkfile" ] ; then
1.150     thfr     1467:                # games without framework files:
                   1468:                # Atom Zombie Smasher, Eliza, Molek-Syntez, Exapunks, Opus Magnum (Lightning.exe),
                   1469:                # Shenzhen I/O, SpaceChem (64bit and fullscreen update from 2020-07-15), Streets of Fury EX
1.196     thfr     1470:                if [ -f "$gamedir/AtomZombieSmasher.exe" ] ; then
                   1471:                        if ls $(echo "$depdir" | tr -s ':' ' ') | grep -q "libatomstb\.so"
1.150     thfr     1472:                        then
1.153     thfr     1473:                                debug_echo "\tfound libatomstb library in a library directory"
1.150     thfr     1474:                        else
1.153     thfr     1475:                                # add libatomstb to needlibarray
1.201     thfr     1476:                                if [ "$(inarray libatomstb.so "$needlibarray")" = "false" ]
                   1477:                                then
1.202     thfr     1478:                                        needlibarray[$((${#needlibarray[*]} + 1))]="$libatomstb.so"
1.153     thfr     1479:                                        debug_echo "\tlibatomstb.so added to array"
1.150     thfr     1480:                                fi
                   1481:                        fi
1.196     thfr     1482:                elif    [ -f "$gamedir/Eliza.exe" ] \
                   1483:                        || [ -f "$gamedir/MOLEK-SYNTEZ.exe" ] \
                   1484:                        || [ -f "$gamedir/EXAPUNKS.exe" ] \
                   1485:                        || [ -f "$gamedir/Lightning.exe" ] \
                   1486:                        || [ -f "$gamedir/Shenzhen.exe" ] \
                   1487:                        || [ -f "$gamedir/SpaceChem.exe" ] \
                   1488:                        || [ -f "$gamedir/Hammerwatch.exe" ] \
                   1489:                        || [ -f "$gamedir/SOR4.exe" ] \
                   1490:                        || [ -f "$gamedir/MobiusFront83.exe" ] \
                   1491:                        || [ -f "$gamedir/Proteus.exe" ]
                   1492:                then
1.150     thfr     1493:                        debug_echo "\nCompatible game without XNA/FNA framework file found."
1.196     thfr     1494:                        debug_echo "Creating \$HOME/Desktop directory which is needed for Zachtronics games"
1.150     thfr     1495:                        mkdir -p "$HOME/Desktop"
                   1496:                else
1.154     thfr     1497:                        found_xna=0
                   1498:                        IFS='
                   1499:                '
1.156     thfr     1500:                        for f in $(find . -maxdepth 1 \( -iname "*.exe" -o -iname "*.dll" \) -exec file {} \; \
1.196     thfr     1501:                                | grep -F "Mono/.Net assembly"); do
                   1502:                                f="$(echo "$f" | cut -d : -f 1)"
1.154     thfr     1503:                                debug_echo "Checking $f for XNA"
1.203     thfr     1504:                                if ! $(monodis --assemblyref "$f" 2>&1 | grep -Fqim1 "Microsoft.Xna.Framework")
1.199     thfr     1505:                                then
                   1506:                                        found_xna=1
                   1507:                                        break
                   1508:                                fi
1.154     thfr     1509:                        done
                   1510:                        IFS=$SAVEIFS
1.199     thfr     1511:                        if [ $found_xna -gt 0 ]; then
1.196     thfr     1512:                                debug_echo "Found XNA reference"
                   1513:                                xnasetup
                   1514:                        else
                   1515:                                echo "No FNA, MonoGame or XNA reference found"
                   1516:                                exit 1
                   1517:                        fi
1.150     thfr     1518:                fi
                   1519:        fi
                   1520:
1.196     thfr     1521:        if [ "$setup_frameworkfile" = "FNA.dll" ] && { [ "$frameworkmajor" -lt 16 ] || { [ "$frameworkmajor" -eq 16 ] && [ "$frameworkminor" -lt 5 ];};}
1.153     thfr     1522:        then
                   1523:                fna_warning=1
1.150     thfr     1524:        fi
                   1525:
                   1526:        check_nlog
                   1527:
1.153     thfr     1528:        set -A configfilesarray         # empty the array
                   1529:        nconfigfilesarray=0             # TODO: is this really needed?
1.150     thfr     1530:        debug_echo "Identifying config files..."
                   1531:        IFS="
1.152     thfr     1532: "
1.205     thfr     1533:        if [ -f "$gamedir"/*.config ]; then
                   1534:                for cfile in "$gamedir"/*.config; do
                   1535:                        cfile="$(basename "$cfile")"
                   1536:                        debug_echo "    found config file: $cfile"
                   1537:                        configfilesarray[$((${#configfilesarray[*]} + 1))]="$cfile"
                   1538:                        nconfigfilesarray=$((nconfigfilesarray + 1))
                   1539:                done
                   1540:        fi
1.150     thfr     1541:        IFS=$SAVEIFS
1.200     thfr     1542:        debug_echo "Done identifying config files.\n"
1.150     thfr     1543:
1.191     thfr     1544:        if [ $nolibcheck -eq 1 ] ; then
                   1545:                debug_echo "skipping library checks"
1.150     thfr     1546:        else
1.191     thfr     1547:                # identify required libraries in .config files and lib{,64} directories
                   1548:                # TODO: filenames not whitespace-safe (but should not be used in such files anyway)
1.196     thfr     1549:                printdash "$(debug_echo "Identifying libraries required by the game...")"
1.191     thfr     1550:
                   1551:                #for MidBoss, add SDL2_image_compact to needlib
1.196     thfr     1552:                [ -f "$gamedir/MidBoss*" ] && \
1.202     thfr     1553:                        needlibarray[$((${#needlibarray[*]} + 1))]="libSDL2_image_compact.so"
1.191     thfr     1554:
                   1555:                libraryname "lib64"
                   1556:                libraryname "lib"
                   1557:                libraryname "x64"
                   1558:                libraryname "x86"
                   1559:
1.206     thfr     1560:                debug_echo "\nChecking for library references in config files..."
1.191     thfr     1561:                if [ $nconfigfilesarray -lt 1 ]; then
1.206     thfr     1562:                        debug_echo "...No config files found."
1.191     thfr     1563:                else
                   1564:                        cfile=""
                   1565:                        IFS="
1.152     thfr     1566: "
1.196     thfr     1567:                        for cfile in "${configfilesarray[@]}"; do
1.191     thfr     1568:                                IFS=$SAVEIFS
                   1569:                                debug_echo "\t$cfile"
1.207     thfr     1570:                                linuxlines=$(grep "os\=\"linux" "$gamedir/$cfile") \
                   1571:                                        || debug_echo "no os=linux entries in $cfile"
1.191     thfr     1572:                                for libstring in $(echo "$linuxlines" | sed -n -E "s/.*target=\"([^\"]+).*/\1/p"); do
                   1573:                                        # Fix where library name includes directory information
                   1574:                                        libstring=$(echo "$libstring" | sed -E 's/^.\///')
                   1575:                                        # remove directories at the start of lib name
                   1576:                                        libstring=$(echo "$libstring" | sed -E 's/^.*\///')
                   1577:                                        debug_echo -n "\t\tFound library string: $libstring"
                   1578:                                        # sort out libs that need to be ignored
1.202     thfr     1579:                                        if [ "$(validlib "$libstring")" = "false" ]
                   1580:                                        then
1.191     thfr     1581:                                                debug_echo " - ignored"
                   1582:                                                continue
                   1583:                                        fi
                   1584:                                        libstring=$(trunklibnam "$libstring")
                   1585:                                        debug_echo -n " -> $libstring"
                   1586:                                        # add to libstring to needlibarray if not in there yet
1.196     thfr     1587:                                        case "$(inarray "$libstring" "$needlibarray")" in
1.201     thfr     1588:                                                "true")
1.196     thfr     1589:                                                        debug_echo " - already in array"
                   1590:                                                        ;;
1.201     thfr     1591:                                                "false")
1.202     thfr     1592:                                                        needlibarray[$((${#needlibarray[*]} + 1))]="$libstring"
1.196     thfr     1593:                                                        debug_echo " - added to array"
                   1594:                                                        ;;
                   1595:                                                *)
                   1596:                                                        printf '\n\t - ERROR: inarray returned with unexpected error\n\n'
                   1597:                                                        exit 1
1.207     thfr     1598:                                                ;;
1.196     thfr     1599:                                        esac
1.191     thfr     1600:                                done
1.150     thfr     1601:                        done
1.191     thfr     1602:                        debug_echo "Done with identifying libraries in config files"
                   1603:                fi
                   1604:                debug_echo "Done with identification of needed libraries."
1.150     thfr     1605:        fi
                   1606:
1.206     thfr     1607:        debug_echo -n "\nChecking if libpng filename needs fixing..."
1.202     thfr     1608:        i=1
                   1609:        while [ "$i" -le "${#needlibarray[@]}" ]; do
                   1610:                needlibarray[i]="$(echo "${needlibarray[i]}" | sed -E "s/(libpng)..(\.so.*)/\1\2/")"
                   1611:                i=$((i + 1))
                   1612:        done
1.150     thfr     1613:        debug_echo " done.\n"
                   1614:
                   1615:        # Check if the libraries are available on the system (/usr/local/lib).
                   1616:        # If not, break and inform user which libraries need to be installed.
                   1617:
1.202     thfr     1618:        debug_echo "Checking installed libraries... "
1.150     thfr     1619:        # missinglibs[*] accumulates missing library names to inform user
                   1620:        missinglibs=""
                   1621:        for needlib in ${needlibarray}; do
1.196     thfr     1622:                if ls $(echo "$depdir" | tr -s ':' ' ') | grep -q "$needlib"
1.150     thfr     1623:                then
                   1624:                        IFS=$SAVEIFS
                   1625:                        debug_echo "\tfound library for: $needlib"
                   1626:                else
                   1627:                        IFS=$SAVEIFS
                   1628:                        debug_echo "\tNot found: $needlib"
                   1629:                        missinglibs="$missinglibs$needlib "
                   1630:                fi
                   1631:        done
1.157     thfr     1632:        debug_echo "done.\n"
1.150     thfr     1633:
                   1634:        if [ -n "${missinglibs}" ]; then
1.200     thfr     1635:                printf '\nCould not find the following libraries:\n\n%b\n' "${missinglibs}"
1.150     thfr     1636:                exit 1
                   1637:        fi
                   1638:
                   1639:        # identify all .config files that do dllmap and move out of the way
                   1640:        debug_echo 'moving .config files with dllmap out of the way'
1.189     thfr     1641:        if [ ! -d "$gamedir/fnaify-backup" ] ; then
1.150     thfr     1642:                mkdir -p "$gamedir/fnaify-backup"
                   1643:        fi
                   1644:        IFS="
1.152     thfr     1645: "
1.196     thfr     1646:        for config_file in "${configfilesarray[@]}"; do
1.150     thfr     1647:                IFS=$SAVEIFS
1.196     thfr     1648:                if [ ! -h "$config_file" ] && grep -q "dllmap" "$config_file"; then
1.150     thfr     1649:                        mv "$config_file" "$gamedir/fnaify-backup/"
                   1650:                fi
                   1651:        done
1.151     thfr     1652:
                   1653:        debug_echo "Moving some bundled dll files into fnaify-backup subfolder... "
                   1654:        for file in $monofilearray; do
                   1655:                if [ -e "$gamedir/$file" ]; then
                   1656:                        debug_echo "\tFound bundled mono file: $file"
                   1657:                        mkdir -p "$gamedir/fnaify-backup"
                   1658:                        mv "$gamedir/$file" "$gamedir/fnaify-backup/"
                   1659:                fi
                   1660:        done
                   1661:        debug_echo " done."
                   1662:
                   1663:        # if necessary, replace FNA.dll
                   1664:        fna_replace=""
                   1665:        lastdir=""
                   1666:        if [ $fna_warning -eq 1 ]; then
1.196     thfr     1667:                if [ "$interaction" = "i" ] ; then
                   1668:                        printf '\nWARNING: version of FNA.dll potentially incompatble!\n'
1.151     thfr     1669:                        echo "Fetch FNA 17.12 from GitHub, compile, and replace bundled FNA.dll?"
                   1670:                        echo "FNA is distributed under Microsoft Public License. The license"
                   1671:                        echo "can be viewed here:"
                   1672:                        echo "https://github.com/FNA-XNA/FNA/blob/master/licenses/LICENSE"
                   1673:                        echo -n "Proceed with replacing FNA with version 17.12 (recommended)? [y/n] "
1.196     thfr     1674:                        until [ "$fna_replace" = "y" ] || [ "$fna_replace" = "n" ]; do
                   1675:                                read -r fna_replace
1.151     thfr     1676:                        done
1.196     thfr     1677:                elif [ "$interaction" = "y" ] ; then
1.151     thfr     1678:                        fna_replace="y"
                   1679:                else
                   1680:                        fna_replace="n"
                   1681:                fi
                   1682:
                   1683:                if [ "$fna_replace" = "y" ]; then
                   1684:                        install_fna 17.12
                   1685:                        fna_warning=0
                   1686:                fi
                   1687:        fi
                   1688:
                   1689:        symlink_mg_libs
1.149     thfr     1690:        iomap
                   1691:
                   1692:        if [ -n "${licenses}" ]; then
1.196     thfr     1693:                printf 'Installed modules are under the following license(s):\n\n'
1.149     thfr     1694:                echo "${licenses}"
                   1695:        fi
                   1696:        if [ $fna_warning -eq 1 ]; then
1.196     thfr     1697:                printf '\nWARNING: version of FNA.dll potentially incompatible!\n'
                   1698:                printf "If the game doesn't run, try running 'fnaify -i' (or 'fnaify -y').\n\n"
1.149     thfr     1699:        fi
                   1700:        if [ $nlog_warning -eq 1 ]; then
1.196     thfr     1701:                printf '\nWARNING: version of NLog.dll potentially incompatible!\n'
                   1702:                printf "If the game doesn't run, try running 'fnaify -i' (or 'fnaify -y').\n\n"
1.149     thfr     1703:        fi
                   1704:
1.152     thfr     1705:        touch .fnaify_ready
1.149     thfr     1706: }
                   1707:
                   1708: ###    END OF VARIABLES AND FUNCTIONS  ###
                   1709:
                   1710: ###################
                   1711: ###    MAIN    ###
                   1712: ###################
                   1713:
1.196     thfr     1714: process_options "$@"
1.199     thfr     1715: if [ $force_setup -gt 0 ]
1.196     thfr     1716: then
                   1717:        setup
                   1718:        run
                   1719: else
                   1720:        [ ! -e "$gamedir/.fnaify_ready" ] && setup
                   1721:        run
                   1722: fi

Contact: <mail@mail.thfr.info>