File: [local] / projects / fnaify / fnaify (download)
Revision 1.208, Thu Jan 6 17:21:01 2022 UTC (4 months, 1 week ago) by thfr
Branch: MAIN
Changes since 1.207: +8 -3 lines
add some of the symlinks for SnailsXNA
|
#!/usr/bin/env ksh
set -o errexit
set -o pipefail
FNAIFY_VERSION=3.0
#########################################################################
# fnaify #
# ====== #
# #
# Run FNA/XNA games on OpenBSD #
# #
# Copyright (c) 2017-2020 Thomas Frohwein #
# portability fixes by Mariusz Zaborski (oshogbo) #
# #
# FNA is a reimplementation of the Microsoft XNA Game Studio 4.0 #
# Refresh libraries. #
# Thanks to the great work by Ethan Lee (flibitijibibo) games using FNA #
# are highly portable and can even run on OpenBSD. Please refer to #
# https://fna-xna.github.io/ for more information about FNA. #
# #
# License: ISC #
#########################################################################
# TODO:
# - fix TODOs
# - fails to detect XNA in Streets of Fury EX because of whitespace; resolved after renaming .exe
# - update the creator for dllmap file; based on fnaify.dllmap.config
# - mention package fnaify-extralibs in documentation
# - add option to add runtime exe_flags to run mode
# - AVNT: find a way to have Steam deactivated for this one in libSteamworksNative.so
# - add flag to create log file (for fnaify, as well as the output from the game)
# - document '--' to end getopts parsing; can make it clear when to pass remaining args to game
# - add check for ffmpeg if needed
USAGE="
Usage:
$(basename "$0") [-i|-y] [-hsv] [-c configfile] [-D depdir] [-d gamedir] [-f frameworkfile | -F frameworkversion] [-m monopath] [userflags]
-c: specify config file for dllmap
-D: add directory to native library loader
-d: game directory
-F: framework version
-f: framework file
-h: print usage information
-i: interactive mode
-m: add directories to MONO_PATH
-n: skip the library check
-s: force (re-)running setup
-y: non-interactive mode; automatically replies 'yes' to all recommended choices
-V: display version
-v: verbose output
<userflags> are optional. These arguments are passed to the game runtime.
"
depdir="/usr/local/lib:/usr/X11R6/lib" # /usr/X11R6/lib is location of libfreetype.so on OpenBSD
fnadir="/usr/local/share/FNA"
gamedir="$PWD"
interaction=n # y|n|i: yes to all, no to all, interactive
debug=
licenses=
gameconfig=
force_setup=0
nolibcheck=0
frameworkfile=
setup_frameworkfile=
frameworkversion=
setup_frameworkversion=
frameworkmajor=
frameworkminor=
userflags=
monopath="${MONO_PATH}"
netstub_commit=e7d890e0ede0caa9e76ef37af6070344e3ab0abf
newline='
'
SAVEIFS=$IFS
exefile=
nexefile=0 # TODO: is nexefile really needed?
my_exe=""
exe_flags=""
exe_env=""
fna_warning=0
nlog_warning=0
set -A needlibarray # array that will hold the names of needed libraries
FNAIFY_DEBUG=false
if [ -d "/usr/local/lib/steamworks-nosteam" ] ; then
monopath="${monopath}:/usr/local/lib/steamworks-nosteam"
depdir="/usr/local/lib/steamworks-nosteam:$depdir"
fi
if [ -d "$fnadir" ] ; then
monopath="${monopath}:${fnadir}"
fi
if [ -d "/usr/local/share/steamstubs" ]; then
monopath="${monopath}:/usr/local/share/steamstubs"
fi
if [ -d "/usr/local/share/fnaify-libs" ]; then
depdir="/usr/local/share/fnaify-libs:$depdir"
fi
# array of lib names to ignore for the configuration checking
ignoredarray="
FarseerPhysics.Portable.xml
libCommunityExpressSW.so
libCSteamworks.so
libGalaxy64.so
libGalaxyCSharpGlue.so
libGalaxy.so
libParisSteam.so
libSkiaSharp.so
libSteamWrapper.so
libXNAFileDialog.so
libXNAWebRenderer.so
libsteam_api.so
libcef.so
libfmod.so
libfmodex.so
libfmodstudio.so
liblua53.so
libtiny_jpeg.so
steamwrapper.so
steam_appid.txt
"
# array of mono files that need to be removed from the game folder
monofilearray="
CSteamworks.dll
I18N.CJK.dll
I18N.MidEast.dll
I18N.Other.dll
I18N.Rare.dll
I18N.West.dll
I18N.dll
Microsoft.CSharp.dll
Mono.CSharp.dll
Mono.Posix.dll
Mono.Security.dll
Steam.dll
System.Configuration.dll
System.Configuration.Install.dll
System.Core.dll
System.Data.dll
System.Design.dll
System.Drawing.dll
System.IO.Compression.FileSystem.dll
System.IO.Compression.dll
System.Management.dll
System.Net.dll
System.Numerics.dll
System.Runtime.Serialization.dll
System.Security.dll
System.ServiceModel.dll
System.Transactions.dll
System.Web.Extensions.dll
System.Web.Http.dll
System.Web.Services.dll
System.Web.dll
System.Windows.Forms.dll
System.Xml.Linq.dll
System.Xml.dll
System.dll
WindowsBase.dll
libMonoPosixHelper.so
libMonoPosixHelper.so.x86
libMonoPosixHelper.so.x86_64
libSteamworksNative.so
monoconfig
monomachineconfig
mscorlib.dll
"
configbasearray="
BlitNet.dll
CDGEngine.dll
CommunityExpress.dll
FMOD.dll
FNA.dll
GameClasses.dll
MonoGame.Framework.dll
Nuclex.Input.dll
OpenAL-CS.dll
SDL2#.dll
SDL2-CS.dll
"
debug_echo()
{
[ "$FNAIFY_DEBUG" = "false" ] && return
if [ "${1}" = '-n' ]; then
printf '%b' "$2"
else
printf '%b\n' "$1"
fi
}
printdash()
{
string=
string="$*"
if [ -z "$string" ]; then
return
fi
printf '%b\n' "$string"
c=1
dashes=
while [ $c -lt ${#string} ]
do
dashes="${dashes}-"
# $((...)) for arithmetic substitution
c=$((c+1))
done
echo "$dashes"
}
inarray() # check if $1 is in array $2
{
firstarg="$1"
shift 1
if echo "$*" | grep -q "$firstarg"
then
echo "true"
else
echo "false"
fi
}
# function to find the latest present library. Return -1 if none found.
# $1 is the basename of the library without the version suffix (e.g. /usr/lib/libc.so)
# it will return the filename of the latest library version (e.g. /usr/lib/libc.so.96.0)
latest_syslib()
{
if [ -z "$1" ] ; then
return 1
fi
find "$(dirname "$1")" -maxdepth 1 -name "$(basename "$1")*" | tail -1
}
trunklibnam() # truncate library name
{
libnam="$1"
libnam="$(echo "$libnam" | sed -n -E "s/[\.0-9]*$//p")"
echo "$libnam" | sed -E "s/(libSDL2[^-]*)-2\.0(\.so.*)/\1\2/"
}
validlib() # returns "false" if $1 is in ignoredarray, otherwise "true"
{
libnam="$(trunklibnam "$1")"
if echo \""$ignoredarray"\" | grep -q "$libnam"; then
echo "false"
elif echo \""$libnam"\" | grep -q '\.dll[ \t]*'; then
echo "false"
else
echo "true"
fi
}
symlink_mg_libs()
{
set -A mg_subdirs x64 x86
debug_echo "\nChecking for MonoGame x64/x86 dir to create symlinks"
if [ ! -e "$gamedir/x64" ] && [ ! -e "$gamedir/x86" ] ; then
debug_echo "...Couldn't find directories x64 or x86 in $gamedir\n"
else
for d in "${mg_subdirs[@]}" ; do
debug_echo "\nProcessing library directory $gamedir/$d"
for file in $gamedir/$d; do
# sort out libs that need to be ignored
if [ "$(validlib "$file")" = "true" ]
then
debug_echo "\tignored file: $file"
continue
fi
debug_echo "\tfound library file: $file. Replacing with symlink..."
trunk=$(trunklibnam "$file")
rm "$gamedir/$d/$file"
debug_echo -n "\t\tchecking for location of $trunk... "
if [ -n "$(latest_syslib "/usr/local/lib/$trunk")" ] ; then
debug_echo "found in /usr/local/lib!"
trunkpath="/usr/local/lib/$trunk"
elif [ -n "$(latest_syslib "/usr/X11R6/lib/$trunk")" ] ; then
debug_echo "found in /usr/X11R6/lib!"
trunkpath="/usr/X11R6/lib/$trunk"
elif [ -n "$(latest_syslib "/usr/lib/$trunk")" ] ; then
debug_echo "found in /usr/lib!"
trunkpath="/usr/lib/$trunk"
else
debug_echo "NOT FOUND!!"
trunkpath=
printf "\n\t - ERROR: couldn't find system lib for %s\n" "$file"
fi
ln -s "$(latest_syslib "$trunkpath")" "$gamedir/$d/$file"
done
debug_echo "Done with library directory $gamedir/$d"
done
debug_echo "\nCreating libdl.so.2 symlink\n"
[ ! -e "$gamedir/libdl.so.2" ] && \
ln -s "$(latest_syslib /usr/lib/libc.so)" "$gamedir/libdl.so.2"
fi
}
selectexe()
{
debug_echo "\nexecutable assembly selection routine"
IFS="
"
for xfile in $(cd "$gamedir" && find . -maxdepth 1 -type f -iname "*.exe" -exec basename {} \; | sort)
do
if echo "$xfile" | ! grep -q vshost && \
echo "$xfile" | ! grep -iq config && \
echo "$xfile" | ! grep -q dotNetFx4 && \
echo "$xfile" | ! grep -q Updater
then
exefile="$exefile$xfile:"
nexefile=$((nexefile + 1))
fi
done
IFS=$SAVEIFS
if [ $nexefile -gt 1 ]; then
if [ "$interaction" = "y" ] ; then
# TODO: for now just pick the first .exe. Come up with
# better heuristic
my_exe="$(echo "$exefile" | cut -f 1 -d ':')"
else
i=1
while [ $i -le $nexefile ]; do
echo "$i: $(echo "$exefile" | cut -f $i -d ':')"
i=$((i + 1))
done
input_exe=0
while [ ${#input_exe} -gt 2 ] \
|| ! echo "$input_exe" | grep -q '[1-9]' \
|| [ $input_exe -gt $((i - 1)) ]
do
echo -n "Enter number of .exe file to run: "
read -r input_exe
done
# NOTE: this only works for up to 9 candidate files
my_exe="$(echo "$exefile" | cut -f "$input_exe" -d ':')"
fi
elif [ $nexefile -eq 1 ]; then
my_exe="$exefile"
else
# TODO: there appear to be games without .exe, like Streets of Rage 4
printf "ERROR: no .exe file found\n\n"
exit 1
fi
my_exe="$(echo "$my_exe" | sed -E "s/[ \t]$//")" # trim trailing whitespace
}
check_gameconfig()
{
if [ -z "$gameconfig" ] ; then
if [ -f "$HOME/.config/fnaify/fnaify.dllmap.config" ] ; then
gameconfig="$HOME/.config/fnaify/fnaify.dllmap.config"
# check for outdated config file
if [ "$(grep -m 1 "fnaify version $FNAIFY_VERSION" "$gameconfig")" = "" ] ; then
echo "WARNING: $gameconfig appears to be out of date. It is strongly recommended to remove it and re-run $(basename "$0")."
fi
else
if [ -f "$fnadir/FNA.dll.config" ] ; then
gameconfig="$fnadir/FNA.dll.config"
elif [ -f "/usr/local/share/fnaify/fnaify.dllmap.config" ] ; then
gameconfig="/usr/local/share/fnaify/fnaify.dllmap.config"
else # in this case create ~/.config/fnaify/fnaify.dllmap.config
gameconfig="$HOME/.config/fnaify/fnaify.dllmap.config"
debug_echo "creating $gameconfig"
mkdir -p ~/.config/fnaify
cat <<EOF > "$gameconfig"
<!-- mono config file for fnaify -->
<!-- fnaify version 3.0 -->
<configuration>
<dllmap dll="FAudio" target="libFAudio.so"/>
<dllmap dll="MojoShader.dll" target="libmojoshader.so"/>
<dllmap dll="SDL2.dll" target="libSDL2.so"/>
<dllmap dll="SDL2_image.dll" target="libSDL2_image.so"/>
<dllmap dll="SDL2_mixer.dll" target="libSDL2_mixer.so"/>
<dllmap dll="SDL2_ttf.dll" target="libSDL2_ttf.so"/>
<dllmap dll="freetype6" target="libfreetype.so" />
<dllmap dll="freetype6.dll" target="libfreetype.so" />
<dllmap dll="libtheorafile.dll" target="libtheorafile.so"/>
<dllmap dll="libtheoraplay.dll" target="libtheoraplay.so"/>
<dllmap dll="libvorbisfile.dll" target="libvorbisfile.so"/>
<dllmap dll="libvorbisfile-3.dll" target="libvorbisfile.so"/>
<dllmap dll="openal32.dll" target="libopenal.so"/>
<dllmap dll="soft_oal.dll" target="libopenal.so"/>
<dllmap dll="System.Native" target="libmono-native.so"/>
<dllmap dll="System.Net.Security.Native" target="libmono-native.so"/>
<dllmap dll="i:msvcrt" target="libc.so" os="!windows"/>
<dllmap dll="i:msvcrt.dll" target="libc.so" os="!windows"/>
<dllmap dll="msvcr100.dll" target="libc.so"/>
<dllmap dll="i:CommunityExpressSW" target="libcestub.so"/>
<dllmap dll="i:CommunityExpressSW.dll" target="libcestub.so"/>
<dllmap dll="user32.dll">
<dllentry dll="libc.so" name="GetWindowThreadProcessId" target="getthrid"/>
<dllentry dll="libstubborn.so" name="SetWindowsHookEx" target="int_0"/>
<dllentry dll="libstubborn.so" name="GetClipCursor" target="int_0"/>
<dllentry dll="libstubborn.so" name="DestroyIcon" target="int_0"/>
</dllmap>
<dllmap dll="ntdll.dll">
<dllentry dll="libstubborn.so" name="NtQueryInformationProcess" target="int_0"/>
</dllmap>
<dllmap dll="ArkSteamWrapper.dll">
<dllentry dll="libstubborn.so" name="ArkSteamInit" target="int_0"/>
<dllentry dll="libstubborn.so" name="ArkGetPlayerId" target="int_0"/>
</dllmap>
<dllmap dll="CSteamworks">
<dllentry dll="libstubborn.so" name="InitSafe" target="int_0"/>
<dllentry dll="libstubborn.so" name="RestartAppIfNecessary" target="int_0"/>
</dllmap>
<dllmap dll="discord-rpc">
<dllentry dll="libstubborn.so" name="Initialize" target="int_0"/>
<dllentry dll="libstubborn.so" name="Discord_Initialize" target="int_0"/>
<dllentry dll="libstubborn.so" name="Discord_UpdatePresence" target="int_0"/>
<dllentry dll="libstubborn.so" name="Discord_RunCallbacks" target="int_0"/>
</dllmap>
<dllmap dll="BrutallyUnfairDll.dll">
<dllentry dll="libstubborn.so" name="loadSteamDll" target="int_0"/>
<dllentry dll="libstubborn.so" name="initSteamAPI" target="int_0"/>
<dllentry dll="libstubborn.so" name="GetModuleHandle" target="int_0"/>
</dllmap>
<dllmap dll="SteamworksNative">
<dllentry dll="libstubborn.so" name="GetStat" target="int_0"/>
<dllentry dll="libstubborn.so" name="Initialize" target="int_0"/>
<dllentry dll="libstubborn.so" name="RunCallbacks" target="ptr_null"/>
<dllentry dll="libstubborn.so" name="Services_RegisterManagedCallbacks" target="int_0"/>
</dllmap>
<dllmap dll="steamwrapper.dll">
<dllentry dll="libstubborn.so" name="API_RunCallbacks" target="int_0"/>
<dllentry dll="libstubborn.so" name="API_Init" target="int_0"/>
<dllentry dll="libstubborn.so" name="API_Shutdown" target="int_0"/>
<dllentry dll="libstubborn.so" name="Stats_getStat" target="int_0"/>
<dllentry dll="libstubborn.so" name="RestartViaSteamIfNecessary" target="int_0"/>
</dllmap>
<dllmap dll="fmod_event.dll">
<dllentry dll="libstubborn.so" name="FMOD_EventSystem_Create" target="int_0"/>
</dllmap>
<dllmap dll="kernel32">
<dllentry dll="ld.so" name="LoadLibrary" target="dlopen"/>
</dllmap>
<!--<dllmap dll="SteamworksNative.dll" target="libSteamworksNative.so"/>-->
<dllmap dll="SteamWrapper.dll">
<dllentry dll="libstubborn.so" name="SteamWrapper_GetCurrentGameLanguage" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_Init" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_GetUserDataFolder" target="string_empty"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_RunCallbacks" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_LbUploadScore" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_Shutdown" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamWrapper_SetAchievement" target="int_0"/>
</dllmap>
<dllmap dll="steam_api">
<dllentry dll="libstubborn.so" name="SteamAPI_Init" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_RegisterCallback" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_GetHSteamUser" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_GetHSteamPipe" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamInternal_CreateInterface" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUser" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamFriends" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUtils" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMatchmaking" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMatchmakingServers" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUserStats" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamApps" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamNetworking" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamRemoteStorage" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamScreenshots" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamGameSearch" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamHTTP" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamController" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamUGC" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamAppList" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMusic" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamMusicRemote" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamHTMLSurface" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamInventory" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamVideo" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamParentalSettings" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamInput" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamClient_GetISteamParties" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamUser_GetSteamID" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamFriends_GetFriendPersonaName" target="string_empty"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_RequestCurrentStats" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_GetCurrentBetaName" target="string_empty"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_BIsDlcInstalled" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamApps_GetLaunchCommandLine" target="string_empty"/>
<dllentry dll="libstubborn.so" name="SteamUserStats" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamRemoteStorage" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamRemoteStorage_FileExists" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_RunCallbacks" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamRemoteStorage_FileWrite" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_Shutdown" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_GetAchievement" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_SetAchievement" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamUserStats_StoreStats" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_ISteamInput_Init" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamAPI_RestartAppIfNecessary" target="int_0"/>
</dllmap>
<dllmap dll="steam_api64">
<dllentry dll="libstubborn.so" name="SteamAPI_Init" target="int_0"/>
</dllmap>
<dllmap dll="fmodstudio">
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Create" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Initialize" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_SetListenerAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Update" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_LoadBankFile" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetVCA" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_SetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_GetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetEvent" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_LoadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_CreateInstance" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_Is3D" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Start" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetBus" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_SetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetDescription" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetPath" target="int_celeste_event"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bank_LoadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetListenerAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Set3DAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Release" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Stop" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Get3DAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Release" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetParameterValue" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_IsOneshot" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_TriggerCue" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_StopAllEvents" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPlaybackState" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetLowLevelSystem" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetInstanceCount" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_UnloadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_FlushCommands" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetChannelGroup" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetCallback" target="int_0"/>
</dllmap>
<dllmap dll="fmodstudio.dll">
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Create" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Initialize" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_SetListenerAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Update" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_LoadBankFile" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetVCA" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_SetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_VCA_GetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetEvent" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_LoadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_CreateInstance" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_Is3D" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Start" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetBus" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_SetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetDescription" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetPath" target="int_celeste_event"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bank_LoadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetListenerAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Set3DAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Release" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Stop" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_Get3DAttributes" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_Release" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetParameterValue" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_IsOneshot" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_TriggerCue" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_StopAllEvents" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPaused" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_GetPlaybackState" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_GetLowLevelSystem" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_GetInstanceCount" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventDescription_UnloadSampleData" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_LockChannelGroup" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_System_FlushCommands" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_Bus_GetChannelGroup" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_Studio_EventInstance_SetCallback" target="int_0"/>
</dllmap>
<dllmap dll="fmodex">
<dllentry dll="libstubborn.so" name="FMOD_System_Create" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_GetVersion" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_Init" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_SetReverbProperties" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_Update" target="int_0"/>
</dllmap>
<dllmap dll="uP2P.dll">
<dllentry dll="libstubborn.so" name="libuP2P_liaison_init" target="int_1"/>
<dllentry dll="libstubborn.so" name="libuP2P_hook" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_part_read" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_part" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_sync_zero" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_persona_rich" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_liaison_poll" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_fake" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_take" target="int_0"/>
<dllentry dll="libstubborn.so" name="libuP2P_liaison_exit" target="int_0"/>
</dllmap>
<dllmap dll="fmod">
<dllentry dll="libstubborn.so" name="FMOD_System_GetVersion" target="int_fmf_getversion"/>
<dllentry dll="libstubborn.so" name="FMOD_System_SetDSPBufferSize" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_SetAdvancedSettings" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_System_SetSoftwareChannels" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_ChannelGroup_SetVolume" target="int_0"/>
<dllentry dll="libstubborn.so" name="FMOD_ChannelGroup_SetPitch" target="int_0"/>
</dllmap>
<!-- PhotonBridge: Unrailed! -->
<dllmap dll="PhotonBridge">
<dllentry dll="libstubborn.so" name="init" target="int_1"/>
<dllentry dll="libstubborn.so" name="Init" target="int_1"/>
</dllmap>
<dllmap dll="SteamLink.dll">
<dllentry dll="libstubborn.so" name="SteamLink_Init" target="int_1"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetMessageCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetDataReceivedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetPersonaStateChangeCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_Shutdown" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetLobbyChatUpdateCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetLobbyDataUpdatedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetLobbyCreatedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetLobbyEnteredCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetLobbyGameCreatedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetBeginAuthResponseCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetP2PSessionRequestCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetP2PSessionConnectFailCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetAvatarImageLoadedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetSteamServersConnectedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetSteamServersDisconnectedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetSteamServerConnectFailureCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetServerListRefreshCompleteCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetIPCFailureCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetSteamShutdownCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetUserStatsReceivedCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetUserStatsStoredCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetAchievementStoredCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetPolicyResponseCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetGSClientApproveCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetGSClientDenyCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_SetGSClientKickCallbackPtr" target="int_0"/>
<dllentry dll="libstubborn.so" name="SteamLink_GetAchievementUnlockStatus" target="int_0"/>
</dllmap>
</configuration>
EOF
fi
fi
fi
}
libraryname()
{
version="$1"
if [ ! -e "$gamedir/$version" ]; then
debug_echo "Couldn't find library directory $gamedir/$version"
else
debug_echo "\nEntering library directory $gamedir/$version"
for file in "$gamedir"/"$version"/*; do
file="$(basename "$file")"
# sort out libs that need to be ignored
if [ "$(validlib "$file")" = "true" ]
then
debug_echo "\tignored file: $file"
continue
fi
debug_echo -n " found library file: $file"
file=$(trunklibnam "$file")
debug_echo -n " -> $file"
case "$(inarray "$file" "${needlibarray}")" in
"true")
debug_echo " - already in array"
;;
"false")
needlibarray[$((${#needlibarray[*]} + 1))]="$file"
debug_echo ""
;;
*)
printf "\n\tERROR: inarray returned with unexpected error\n\n"
exit 1
;;
esac
done
debug_echo "Done with library directory $gamedir/$version"
fi
}
# install FNA into gamedir; specify version (e.g. 17.12) as $1
# if XNA bridge should be installed, add "xna_bridge" as $2
install_fna()
{
if [ $# -lt 1 ]; then
echo "ERROR: install_fna called with insufficient arguments"
exit 1
fi
fna_version=
if [ "${1}" = 'latest' ]; then
# get version number of latest release from GitHub API
fna_version=$(ftp -Vo - https://api.github.com/repos/FNA-XNA/FNA/releases/latest \
| grep -Eo "\"tag_name\"\:\"[0-9\.]*\"" \
| cut -d\" -f4)
else
fna_version="$1"
fi
printf '\nInstalling FNA %s ...' "${fna_version}\n"
licenses="${licenses}FNA:\t\tMs-PL (https://github.com/FNA-XNA/FNA/blob/master/licenses/LICENSE)${newline}"
lastdir="$PWD"
cd /tmp || exit 1
ftp -V "https://github.com/FNA-XNA/FNA/releases/download/${fna_version}/FNA-$(echo "$fna_version" | tr -d '.').zip"
debug_echo "extracting FNA ${fna_version}"
unzip "FNA-$(echo "$fna_version" | tr -d '.').zip" > /dev/null
if [ $# -gt 1 ] \
&& [ "$2" = "xna_bridge" ]
then
printf '\nInstalling FNA.NetStub for XNA ...\n'
licenses="${licenses}FNA.NetStub:\tMs-PL (https://github.com/FNA-XNA/FNA.NetStub/blob/master/LICENSE)${newline}"
ftp -V https://github.com/FNA-XNA/FNA.NetStub/archive/$netstub_commit.tar.gz
tar zxf $netstub_commit.tar.gz
mv FNA.NetStub-$netstub_commit FNA.NetStub
echo -n "compiling XNA ABI/bridge files. This may take a moment... "
xbuild /p:Configuration=Release FNA/abi/Microsoft.Xna.Framework.sln >> /tmp/fnaify-xbuild.log
echo "done."
cp /tmp/FNA/abi/bin/Release/* "$gamedir/"
else
# Download Vorbisfile-CS to be included in the build
ftp https://raw.githubusercontent.com/flibitijibibo/Vorbisfile-CS/master/Vorbisfile.cs
# add in FNA.Settings.props
cat <<EOF > FNA/FNA.Settings.props
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Include="lib/SDL2-CS/src/SDL2_image.cs" />
<Compile Include="../Vorbisfile.cs" />
</ItemGroup>
</Project>
EOF
echo -n "compiling FNA ${fna_version} with xbuild... "
xbuild /p:Configuration=Release FNA/FNA.sln >> /tmp/fnaify-xbuild.log
echo "done."
echo "Moving FNA.dll to fnaify-backup subdirectory"
mkdir -p "$gamedir/fnaify-backup"
mv "$gamedir/FNA.dll" "$gamedir/fnaify-backup/"
cp /tmp/FNA/bin/Release/FNA.dll "$gamedir"
fi
debug_echo "removing the temporary build directories and returning to previous directory"
rm -rf /tmp/FNA /tmp/FNA.NetStub /tmp/Vorbisfile.cs
cd "$lastdir" || exit 1
}
check_nlog()
{
if [ -f "$gamedir/NLog.dll" ] ; then
nlogversion=$(monodis --assembly "$gamedir/NLog.dll" | grep "Version" | tr -d '[:alpha:]' | tr -d " " | tr -d :)
nlogmajor=$(echo "$nlogversion" | sed -n -E "s/\..*//p")
nlogminor=$(echo "$nlogversion" | sed -n -E "s/[0-9]+\.([0-9]+)\.[0-9]+\.[0-9]+/\1/p")
debug_echo -n "\tNLog.dll version $nlogversion, "
debug_echo -n "major: $nlogmajor, "
debug_echo "minor: $nlogminor"
if [ "$nlogmajor" -lt 4 ] \
&& [ "$interaction" = "i" ]
then
printf '\nInstall NLog 4.6.5 from www.nuget.org? [y/n] '
response=
until [ "$response" = "y" ] || [ "$response" = "n" ]
do
read -r response
done
elif [ "$nlogmajor" -lt 4 ] && [ "$interaction" = "y" ] ; then
response="y"
else
response="n"
fi
if [ "$response" = "y" ] ; then
debug_echo "Moving old NLog.dll out of the way"
mkdir -p "$gamedir/fnaify-backup"
mv "$gamedir/NLog.dll" "$gamedir/fnaify-backup/"
lastdir="$PWD"
mkdir /tmp/nlog
cd /tmp/nlog || exit 1
printf '\nInstalling NLog 4.6.5 ...\n'
licenses="${licenses}NLog:\tBSD 3-clause (https://github.com/NLog/NLog/blob/master/LICENSE.txt)${newline}"
ftp -Vo nlog.4.6.5.nupkg https://www.nuget.org/api/v2/package/NLog/4.6.5
unzip nlog.4.6.5.nupkg > /dev/null
cp lib/net45/NLog.dll "$gamedir/"
cd "$lastdir" || exit 1
rm -rf /tmp/nlog
elif [ "$nlogmajor" -lt 4 ] ; then
nlog_warning=1
fi
fi
}
process_options()
{
while getopts c:Dd:F:f:hil:m:nsVvy o; do
case "$o" in
c) gameconfig="$OPTARG" ;;
D) debug="--debug" ;;
d) gamedir=$(readlink -f "$OPTARG") ;;
f) frameworkfile="$OPTARG" ;;
F) frameworkversion="$OPTARG" ;;
h) echo "$USAGE"; exit 0;;
i) interaction=i ;;
l) depdir="$OPTARG" ;;
m) monopath="$OPTARG" ;;
n) nolibcheck=1 ;;
s) force_setup=1 ;;
V) echo "$FNAIFY_VERSION"; exit 0;;
v) FNAIFY_DEBUG=true ;;
y) interaction=y ;;
--) break ;;
*) ;;
esac
done
debug_echo "options: $*"
debug_echo "OPTIND: $OPTIND"
shift $((OPTIND-1))
debug_echo "options after shift: $*\n"
userflags=$*
}
check_mono_binaries()
{
debug_echo "Checking mono and monodis"
if [ -z "$FNAIFY_MONO" ]; then
FNAIFY_MONO="$(which mono 2>/dev/null)"
fi
[ -z "$FNAIFY_MONO" ] && { \
echo "error finding mono"
exit 1
}
if ! "$FNAIFY_MONO" --version 2>/dev/null >/dev/null
then
echo "error calling mono - aborting... Please make sure that mono is in path or set it in FNAIFY_MONO environment variable!"
exit 1
fi
# check if monodis can be called
if monodis 2>/dev/null
then
echo "error calling monodis - aborting... Please make sure that monodis is in the PATH!"
exit 1
fi
}
iomap()
{
debug_echo "iomap: checking if symlinks for filename cases need to be created"
for f in $(find "$gamedir" -maxdepth 1 -name "*.exe" -exec basename {} \;); do
case $f in
"Dead Pixels.exe" )
ln -sf Sprites Content/sprites
ln -sf Effects Content/Sprites/effects
ln -sf Splash Content/Sprites/splash
ln -sf Items Content/Sprites/InGame/items
ln -sf Grenades Content/Sprites/InGame/grenades
ln -sf Hud Content/Sprites/InGame/hud
ln -sf insideBuildings Content/Sprites/InGame/InsideBuildings
ln -sf Character Content/Sprites/InGame/character
ln -sf City Content/Sprites/InGame/city
ln -sf Traders Content/Sprites/InGame/traders
ln -sf Zombies Content/Sprites/InGame/zombies
ln -sf Objects Content/Sprites/InGame/objects
ln -sf Other Content/Sprites/InGame/other
ln -sf GunShots Content/Sprites/InGame/gunShots
ln -sf Buttons Content/Sprites/buttons
ln -sf Menu Content/Sprites/menu
ln -sf Cursor Content/Sprites/cursor
ln -sf Achievements Content/Sprites/achievements
ln -sf Credits Content/Sprites/credits
ln -sf Font Content/Sprites/font
ln -sf preview Content/Sprites/Preview
ln -sf preview Content/Sprites/Menu/Preview
ln -sf PsxButtons Content/Sprites/buttons/psxButtons
ln -sf Cutscene Content/Sprites/CutScene
ln -sf buildings Content/Sprites/InGame/City/Buildings
ln -sf mainbackground.xnb Content/ConfigSprites/mainBackground.xnb
ln -sf largeCuts.xnb Content/Sprites/effects/largecuts.xnb
ln -sf smallCuts.xnb Content/Sprites/effects/smallcuts.xnb
ln -sf effects Content/Sprites/Effects
ln -sf cuemark.xnb Content/Sprites/effects/cueMark.xnb
ln -sf Static.xnb Content/Sprites/Menu/Preview/static.xnb
;;
AJ1.exe )
ln -sf j_rip.xnb Content/AJ1/j_Rip.xnb
ln -sf j_rip.xnb Content/AJ2/j_Rip.xnb
ln -sf Owlturnneo2.xnb Content/AJ1/owlturnneo2.xnb
ln -sf Owlturnneo2.xnb Content/AJ2/owlturnneo2.xnb
;;
CSTW.exe )
ln -sf paws_Happy.xnb Content/Portrait/Paws/Paws_Happy.xnb
;;
ThePit.exe )
ln -sf UI Content/ui
;;
"Grand Class Melee.exe" )
ln -sf water.xnb Content/Sounds/Water.xnb
ln -sf grass.xnb Content/Sounds/Grass.xnb
ln -sf move.xnb Content/Sounds/Move.xnb
ln -sf select.xnb Content/Sounds/Select.xnb
ln -sf back.xnb Content/Sounds/Back.xnb
ln -sf squire_base.xnb Content/Textures/Players/Squire_base.xnb
ln -sf squire_greyscale.xnb Content/Textures/Players/Squire_greyscale.xnb
ln -sf militia_base.xnb Content/Textures/Players/Militia_base.xnb
ln -sf militia_greyscale.xnb Content/Textures/Players/Militia_greyscale.xnb
ln -sf apprentice_base.xnb Content/Textures/Players/Apprentice_base.xnb
ln -sf apprentice_greyscale.xnb Content/Textures/Players/Apprentice_greyscale.xnb
ln -sf savant_base.xnb Content/Textures/Players/Savant_base.xnb
ln -sf savant_greyscale.xnb Content/Textures/Players/Savant_greyscale.xnb
ln -sf sword.xnb Content/Textures/Weapons/Sword.xnb
ln -sf arrow.xnb Content/Sounds/Arrow.xnb
ln -sf scorch.xnb Content/Sounds/Scorch.xnb
ln -sf bigspeed.xnb Content/Sounds/Bigspeed.xnb
ln -sf frame_ingame_left_ruin.xnb Content/Textures/Menu/frame_ingame_left_Ruin.xnb
ln -sf frame_ingame_left_mire.xnb Content/Textures/Menu/frame_ingame_left_Mire.xnb
ln -sf frame_ingame_right_ruin.xnb Content/Textures/Menu/frame_ingame_right_Ruin.xnb
ln -sf frame_ingame_left_wood.xnb Content/Textures/Menu/frame_ingame_left_Wood.xnb
ln -sf ruin_leaf.xnb Content/Textures/Terrain/Ruin_leaf.xnb
ln -sf frame_ingame_right_wood.xnb Content/Textures/Menu/frame_ingame_right_Wood.xnb
ln -sf bigblow1.xnb Content/Sounds/Bigblow1.xnb
ln -sf ruin_grassmove.xnb Content/Textures/Terrain/Ruin_grassmove.xnb
ln -sf wood_leaf.xnb Content/Textures/Terrain/Wood_leaf.xnb
ln -sf ruin_watermove.xnb Content/Textures/Terrain/Ruin_watermove.xnb
ln -sf castshort.xnb Content/Sounds/Castshort.xnb
ln -sf frame_ingame_right_mire.xnb Content/Textures/Menu/frame_ingame_right_Mire.xnb
ln -sf frame_ingame_left_dune.xnb Content/Textures/Menu/frame_ingame_left_Dune.xnb
ln -sf sword1.xnb Content/Sounds/Sword1.xnb
ln -sf frame_ingame_right_dune.xnb Content/Textures/Menu/frame_ingame_right_Dune.xnb
ln -sf staff1.xnb Content/Sounds/Staff1.xnb
;;
"LaserCat.exe" )
ln -sf audio Content/Audio
;;
"MountYourFriends.exe" )
ln -sf menuBg.xnb Content/images/menubg.xnb
ln -sf humanClean.xnb Content/images/humanclean.xnb
ln -sf humanCleanNorm.xnb Content/images/humancleannorm.xnb
ln -sf menuMarker.xnb Content/images/menumarker.xnb
ln -sf stegersaurusLogo.xnb Content/images/backdrops/stegersauruslogo.xnb
ln -sf UIComponents.xnb Content/images/uicomponents.xnb
ln -sf restrictedArea.xnb Content/images/restrictedarea.xnb
ln -sf goatSheet.xnb Content/images/goatsheet.xnb
ln -sf BP3_SSTRIP_64.xnb Content/images/bp3_sstrip_64.xnb
ln -sf BP3_SSTRIP_32.xnb Content/images/bp3_sstrip_32.xnb
ln -sf keySheet.xnb Content/images/keysheet.xnb
;;
"One Finger Death Punch.exe" )
ln -sf font2.xnb Content/Font2.xnb
ln -sf font5.xnb Content/Font5.xnb
ln -sf font6.xnb Content/Font6.xnb
;;
"PhoenixForce.exe" )
ln -sf LIfeBar.xnb Content/1.4/Boss/lifeBar.xnb
ln -sf firewavexml.xml Content/1.4/Player/fireWavexml.xml
ln -sf firewave.xnb Content/1.4/Player/fireWave.xnb
;;
"Streets of Fury EX.exe" )
ln -sf ShockWave.xnb Content/Texture2D/Shockwave.xnb
;;
"Aces Wild.exe" )
ln -sf HitSparks Content/Sprites/Hitsparks
ln -sf preFabs.awx Content/Data/prefabs.awx
;;
"CameraObscura.exe" )
ln -sf enemies Content/Enemies
ln -sf buttons Content/Buttons
ln -sf ui Content/UI
ln -sf particle Content/Particle
;;
"DLC.exe" )
ln -sf ../../campaigns/dlcquest/texture/awardmentSpriteSheet.xnb Content/base/texture/awardmentSpriteSheet.xnb
ln -sf ../../campaigns/dlcquest/texture/dlcSpriteSheet.xnb Content/base/texture/dlcSpriteSheet.xnb
ln -sf ../../campaigns/dlcquest/data/map Content/base/data/map
ln -sf ../../campaigns/dlcquest/texture/tiles_16x16.xnb Content/base/texture/tiles_16x16.xnb
ln -sf ../../campaigns/dlcquest/texture/skyNightSpriteSheet.xnb Content/base/texture/skyNightSpriteSheet.xnb
ln -sf ../../campaigns/dlcquest/texture/backgroundSpriteSheet.xnb Content/base/texture/backgroundSpriteSheet.xnb
ln -sf ../../campaigns/dlcquest/texture/background2SpriteSheet.xnb Content/base/texture/background2SpriteSheet.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/shopkeep.xnb Content/base/data/npc/shopkeep.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/shopkeep2.xnb Content/base/data/npc/shopkeep2.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/shepherd.xnb Content/base/data/npc/shepherd.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/random.xnb Content/base/data/npc/random.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/filler.xnb Content/base/data/npc/filler.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/blacksmith.xnb Content/base/data/npc/blacksmith.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/sidequest.xnb Content/base/data/npc/sidequest.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/troll.xnb Content/base/data/npc/troll.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/gunsmith.xnb Content/base/data/npc/gunsmith.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/princess.xnb Content/base/data/npc/princess.xnb
ln -sf ../../../campaigns/dlcquest/data/npc/horse.xnb Content/base/data/npc/horse.xnb
;;
"EvilQuest.exe" )
ln -sf Weapons Content/weapons
ln -sf DialogWindow.xnb Content/HUD/dialogWindow.xnb
ln -sf SpellSprites Content/spellSprites
ln -sf PromptMessageWindow.xnb Content/HUD/promptMessageWindow.xnb
ln -sf PromptWindow.xnb Content/HUD/promptWindow.xnb
ln -sf Menu Content/menu
ln -sf smallCursor.xnb Content/Menu/smallcursor.xnb
ln -sf ItemIcons.xnb Content/Menu/itemIcons.xnb
ln -sf SpellIcons.xnb Content/Menu/spellIcons.xnb
ln -sf SplashSymbol.xnb Content/Menu/splashSymbol.xnb
ln -sf SplashChaosoftLogo.xnb Content/Menu/splashChaosoftLogo.xnb
ln -sf SplashGamesText.xnb Content/Menu/splashGamesText.xnb
ln -sf PrisonGalvis_NoShadow.xnb Content/prisonGalvis_NoShadow.xnb
ln -sf EnemySprites Content/enemysprites
ln -sf Galvis_NoShadow.xnb Content/EnemySprites/galvis_noShadow.xnb
ln -sf DemonGalvis.xnb Content/demonGalvis.xnb
ln -sf StunnedEffect.xnb Content/SpellSprites/stunnedEffect.xnb
ln -sf Colorize.xnb Content/colorize.xnb
ln -sf bossDialogMusic.xnb Content/BossDialogMusic.xnb
ln -sf Equip.xnb Content/Menu/equip.xnb
ln -sf MessageWindow.xnb Content/Menu/messageWindow.xnb
ln -sf Shop.xnb Content/shop.xnb
ln -sf Title.xnb Content/Menu/title.xnb
ln -sf TitleNewGame.xnb Content/Menu/titleNewGame.xnb
ln -sf TitleNewGameActive.xnb Content/Menu/titleNewGameActive.xnb
ln -sf GalvisTheme.xnb Content/galvisTheme.xnb
ln -sf FlamesBG.xnb Content/Intro/Screen1/flamesBG.xnb
ln -sf FlamesFG.xnb Content/Intro/Screen1/flamesFG.xnb
ln -sf ForegroundMask.xnb Content/Intro/Screen1/foregroundMask.xnb
ln -sf VillageBGFire.xnb Content/Intro/Screen3/villageBGFire.xnb
ln -sf VillageFG.xnb Content/Intro/Screen3/villageFG.xnb
ln -sf VillageFire.xnb Content/Intro/Screen3/villageFire.xnb
ln -sf Galvis1.xnb Content/Intro/Screen3/galvis1.xnb
ln -sf Galvis2.xnb Content/Intro/Screen3/galvis2.xnb
ln -sf Silhouettes.xnb Content/Intro/Screen4/silhouettes.xnb
ln -sf FullColor.xnb Content/Intro/Screen4/fullcolor.xnb
ln -sf FlamesBG.xnb Content/Intro/Screen4/flamesBG.xnb
ln -sf FlamesFG.xnb Content/Intro/Screen4/flamesFG.xnb
ln -sf ForegroundMask.xnb Content/Intro/Screen4/foregroundMask.xnb
ln -sf ArrestFG1.xnb Content/Intro/Screen5/arrestFG1.xnb
ln -sf ArrestFG2.xnb Content/Intro/Screen5/arrestFG2.xnb
ln -sf ArrestFG3.xnb Content/Intro/Screen5/arrestFG3.xnb
ln -sf GalvisEndingCloseUpBG1.xnb Content/Intro/Screen9/GalvisEndingCloseupBG1.xnb
ln -sf ControlsPC.xnb Content/Menu/controlsPC.xnb
ln -sf amethyst.xnb Content/Amethyst.xnb
ln -sf BattlefieldIntro.xnb Content/BATTLEFIELDINTRO.xnb
ln -sf Prison2.xnb Content/PRISON2.xnb
ln -sf Prison1.xnb Content/PRISON1.xnb
ln -sf Items.xml Data/items.dat
ln -sf NPCs.xml Data/NPCS.dat
;;
"HELLYEAH.exe" )
ln -sf QuadNoir.xnb Content/QUADNOIR.xnb
ln -sf QuadBlanc.xnb Content/QUADBLANC.xnb
ln -sf TRANS_Mask.xnb Content/TRANS_MASK.xnb
ln -sf Popup Content/GAME/HUD/POPUP
ln -sf pop_u_trung.xnb Content/GAME/HUD/Popup/POP_U_TRUNG.xnb
ln -sf popup_cartouche_noir.xnb Content/GAME/HUD/Popup/POPUP_CARTOUCHE_NOIR.xnb
ln -sf popup_barre_rouges.xnb Content/GAME/HUD/Popup/POPUP_BARRE_ROUGES.xnb
ln -sf Menu_\(arial\).xnb Content/TITLE/FONTS/MENU_\(ARIAL\).xnb
ln -sf cursor.xnb Content/PCONLY/CURSORS/CURSOR.xnb
ln -sf viseur.xnb Content/PCONLY/CURSORS/VISEUR.xnb
ln -sf Shaders Content/SHADERS
ln -sf WhiteFlash.xnb Content/Shaders/WHITEFLASH.xnb
ln -sf VaguePoison.xnb Content/Shaders/VAGUEPOISON.xnb
ln -sf Black.xnb Content/Shaders/BLACK.xnb
ln -sf White.xnb Content/Shaders/WHITE.xnb
ln -sf BloomExtract.xnb Content/Shaders/BLOOMEXTRACT.xnb
ln -sf BloomCombine.xnb Content/Shaders/BLOOMCOMBINE.xnb
ln -sf GaussianBlur.xnb Content/Shaders/GAUSSIANBLUR.xnb
ln -sf Sobel.xnb Content/Shaders/SOBEL.xnb
ln -sf RadialBlur.xnb Content/Shaders/RADIALBLUR.xnb
ln -sf VagueFeu.xnb Content/Shaders/VAGUEFEU.xnb
ln -sf ColorEffects.xnb Content/Shaders/COLOREFFECTS.xnb
ln -sf Explosion.xnb Content/Shaders/EXPLOSION.xnb
ln -sf Ripple.xnb Content/Shaders/RIPPLE.xnb
ln -sf RedFilter.xnb Content/Shaders/REDFILTER.xnb
ln -sf Distortion.xnb Content/Shaders/DISTORTION.xnb
ln -sf Lightning.xnb Content/Shaders/LIGHTNING.xnb
ln -sf LoadingWheel.xnb Content/GAME/LOADING/LOADINGWHEEL.xnb
ln -sf LOGO_Sega.xnb Content/LOGO/LOGO_SEGA.xnb
ln -sf LOGO_Arkedo.xnb Content/LOGO/LOGO_ARKEDO.xnb
ln -sf Sounds Content/GAME/WORLD/SOUNDS
ln -sf HY_Sounds.xnb Content/GAME/WORLD/Sounds/HY_SOUNDS.xnb
ln -sf picto_A.xnb Content/GAME/FONTS/PICTO/PICTO_A.xnb
ln -sf picto_B.xnb Content/GAME/FONTS/PICTO/PICTO_B.xnb
ln -sf picto_BK.xnb Content/GAME/FONTS/PICTO/PICTO_BK.xnb
ln -sf picto_LB.xnb Content/GAME/FONTS/PICTO/PICTO_LB.xnb
ln -sf picto_LS.xnb Content/GAME/FONTS/PICTO/PICTO_LS.xnb
ln -sf picto_LT.xnb Content/GAME/FONTS/PICTO/PICTO_LT.xnb
ln -sf picto_PAD.xnb Content/GAME/FONTS/PICTO/PICTO_PAD.xnb
ln -sf picto_RB.xnb Content/GAME/FONTS/PICTO/PICTO_RB.xnb
ln -sf picto_RS.xnb Content/GAME/FONTS/PICTO/PICTO_RS.xnb
ln -sf picto_RT.xnb Content/GAME/FONTS/PICTO/PICTO_RT.xnb
ln -sf picto_ST.xnb Content/GAME/FONTS/PICTO/PICTO_ST.xnb
ln -sf picto_X.xnb Content/GAME/FONTS/PICTO/PICTO_X.xnb
ln -sf picto_Y.xnb Content/GAME/FONTS/PICTO/PICTO_Y.xnb
ln -sf picto_RS1.xnb Content/GAME/FONTS/PICTO/PICTO_RS1.xnb
ln -sf picto_RS2.xnb Content/GAME/FONTS/PICTO/PICTO_RS2.xnb
ln -sf picto_RS3.xnb Content/GAME/FONTS/PICTO/PICTO_RS3.xnb
ln -sf picto_RS4.xnb Content/GAME/FONTS/PICTO/PICTO_RS4.xnb
ln -sf picto_360.xnb Content/GAME/FONTS/PICTO/PICTO_360.xnb
ln -sf saving.xnb Content/LOGO/SAVING.xnb
ln -sf branchetonpad.xnb Content/PCONLY/MENUS/BRANCHETONPAD.xnb
ln -sf pckey.xnb Content/PCONLY/MENUS/PCKEY.xnb
ln -sf mousecenter.xnb Content/PCONLY/MENUS/MOUSECENTER.xnb
ln -sf mousedefault.xnb Content/PCONLY/MENUS/MOUSEDEFAULT.xnb
ln -sf mousedirections.xnb Content/PCONLY/MENUS/MOUSEDIRECTIONS.xnb
ln -sf mouseleftbt.xnb Content/PCONLY/MENUS/MOUSELEFTBT.xnb
ln -sf mouserightbt.xnb Content/PCONLY/MENUS/MOUSERIGHTBT.xnb
ln -sf mousewheelup.xnb Content/PCONLY/MENUS/MOUSEWHEELUP.xnb
ln -sf mousewheeldown.xnb Content/PCONLY/MENUS/MOUSEWHEELDOWN.xnb
ln -sf ls.xnb Content/PCONLY/MENUS/LS.xnb
ln -sf ls1.xnb Content/PCONLY/MENUS/LS1.xnb
ln -sf ls2.xnb Content/PCONLY/MENUS/LS2.xnb
ln -sf ls360.xnb Content/PCONLY/MENUS/LS360.xnb
ln -sf rs1.xnb Content/PCONLY/MENUS/RS1.xnb
ln -sf rs2.xnb Content/PCONLY/MENUS/RS2.xnb
ln -sf rs3.xnb Content/PCONLY/MENUS/RS3.xnb
ln -sf rs4.xnb Content/PCONLY/MENUS/RS4.xnb
ln -sf "INT_Radar_(good_girl).xnb" "Content/GAME/FONTS/INT_RADAR_(GOOD_GIRL).xnb"
ln -sf "DLG_Name_(trashand).xnb" "Content/GAME/FONTS/DLG_NAME_(TRASHAND).xnb"
ln -sf Particules Content/TITLE/PARTICULES
ln -sf boum.xnb Content/TITLE/Particules/BOUM.xnb
ln -sf flameches.xnb Content/TITLE/Particules/FLAMECHES.xnb
ln -sf fumee_background_flou.xnb Content/TITLE/Particules/FUMEE_BACKGROUND_FLOU.xnb
ln -sf fumee_noire.xnb Content/TITLE/Particules/FUMEE_NOIRE.xnb
ln -sf gaz_multicolor.xnb Content/TITLE/Particules/GAZ_MULTICOLOR.xnb
ln -sf TITLE_Cartouche.xnb Content/TITLE/TITLE_CARTOUCHE.xnb
ln -sf TITLE_Subtitle-EN.xnb Content/TITLE/TITLE_SUBTITLE-EN.xnb
ln -sf TITLE_Logo.xnb Content/TITLE/TITLE_LOGO.xnb
ln -sf TITLE_FlameScroll.xnb Content/TITLE/TITLE_FLAMESCROLL.xnb
ln -sf TITLE_LogoMask.xnb Content/TITLE/TITLE_LOGOMASK.xnb
ln -sf TITLE_Background.xnb Content/TITLE/TITLE_BACKGROUND.xnb
ln -sf TITLE_Select.xnb Content/TITLE/TITLE_SELECT.xnb
;;
"HonourRuns.exe" )
ln -sf Sprites Content/sprites
ln -sf Textures Content/textures
ln -sf Levels Content/levels
;;
"POOF.exe" )
ln -sf QuadNoir.xnb Content/QUADNOIR.xnb
ln -sf QuadBlanc.xnb Content/QUADBLANC.xnb
ln -sf TRANS_Mask.xnb Content/TRANS_MASK.xnb
;;
# beware, SSDD and SSDDXXL have the same named SSGame.exe
"SSGame.exe" )
# SSDDXXL
ln -s HUD_ShopBackground.xnb Content/textures/menus/HUD_Shopbackground.xnb
ln -s GLOBAL.xnb Content/levels/global.xnb
ln -s HUD_challenge_skull.xnb Content/textures/menus/hud_challenge_skull.xnb
ln -s LEVEL1.xnb Content/levels/level1.xnb
# SSDD
ln -s FRONT.xnb Content/levels/front.xnb
;;
"TheFallOfGods2.exe" )
ln -sf Data Content/data
;;
"Snails.exe" )
ln -s ScreensData.xnb Content/screens/screensdata.xnb
ln -s footerMessage.xnb Content/fonts/footermessage.xnb
ln -s MainMenu.xnb Content/screens/mainmenu.xnb
ln -s UISnailsMenu.xnb Content/screens/controls/uisnailsmenu.xnb
ln -s UIMainMenuBodyPanel.xnb Content/screens/controls/uimainmenubodypanel.xnb
esac
done
IFS=$SAVEIFS
}
xnasetup()
{
if [ ! -d "$fnadir" ] ; then
if [ "$interaction" = "i" ] ; then
printf '\nInstall FNA files from GitHub to for this XNA application? [y/n] '
response=
until [ "$response" = "y" ] || [ "$response" = "n" ]
do
read -r response
done
elif [ "$interaction" = "y" ] ; then
response="y"
else
response="n"
fi
if [ "$response" = "y" ]; then
install_fna latest xna_bridge
else
printf 'Failed to install FNA/XNA files. Try running with -i or -y flag\n'
exit 1
fi
fi
# convert .wma to .ogg and .wmv to .ogv
# https://gist.github.com/flibitijibibo/c97bc14aab04b1277d8ef5e97fc9aeff
IFS="
"
# TODO: check for errors on return of these commands
echo "checking for WMA/WMV files and converting. This may take several minutes..."
for afile in $(find "$gamedir" -name "*.wma"); do
echo "converting $afile to OGG"
ffmpeg -loglevel fatal -i "$afile" -c:a libvorbis -q:a 10 \
"$(echo "$afile" | rev | cut -d. -f2-$(($(echo "$afile" \
| tr -dc '.' | wc -c) + 1)) | rev).ogg" \
|| echo "...skipping..."
done
for vfile in $(find . -name "*.wmv"); do
echo "converting $vfile to OGV"
ffmpeg -loglevel fatal -i "$vfile" -c:v libtheora -q:v 10 -c:a libvorbis \
-q:a 10 "$(echo "$vfile" | rev | cut -d. -f2-$(($(echo "$vfile" \
| tr -dc '.' | wc -c) + 1)) | rev).ogv" \
|| echo "...skipping..."
done
IFS=$SAVEIFS
echo " done."
}
get_setup_frameworkfile()
{
if [ -e "$gamedir/FNA.dll" ] ; then
setup_frameworkfile="$gamedir/FNA.dll"
elif [ -e "$gamedir/MonoGame.Framework.dll" ] ; then
setup_frameworkfile="$gamedir/MonoGame.Framework.dll"
fi
}
get_frameworkversion()
{
if [ -f "$1" ] ; then
monodis --assembly "$1" | grep -F Version | sed -E 's/Version:[[:blank:]]*//'
fi
}
get_frameworkmajor()
{
echo "$1" | sed -n -E "s/([0-9]+)\.[0-9\.]+/\1/p"
}
get_frameworkminor()
{
# strip leading zeros
echo "$1" | sed -n -E "s/[0-9]+\.([0-9]+).*/\1/p" | sed "s/^0*//"
}
check_eagle_island()
{
{ [ -f "$gamedir/EagleIsland.exe" ] && \
[ "$(basename "$gamedir")" != "Linux" ]; } && \
{ \
debug_echo "correct gamedir for Eagle Island"
gamedir="${gamedir}/Linux"
}
}
run()
{
check_eagle_island
[ -e "$gamedir/.fnaify_ready" ] || { echo "ERROR: setup not completed."; exit 1; }
check_mono_binaries
cd "$gamedir" || exit 1
selectexe
check_gameconfig
[ -e "$gameconfig" ] || { echo "ERROR: provided gameconfig file not existent: $gameconfig"; exit 1; }
debug_echo "gameconfig: $gameconfig"
# Quirks
my_exe="$(echo "$my_exe" | tr -d '\:')"
case "$my_exe" in
Blueberry.exe|Shenzhen.exe|ThePit.exe|Terraria.exe )
exe_env="${exe_env}MONO_FORCE_COMPAT=1 "
;;
Hacknet.exe )
exe_flags="${exe_flags}-disableweb "
;;
ScourgeBringer.exe )
exe_flags="${exe_flags}-noSound "
;;
MidBoss.exe )
if [ -e fnaify.dllmap.MidBoss.config ] &&
[ "$(diff -U 0 "$gameconfig" fnaify.dllmap.MidBoss.config | \
wc -l)" -eq 5 ]
then
debug_echo "fnaify.dllmap.MidBoss.config up to date."
else
debug_echo "fnaify.dllmap.MidBoss.config is missing or out of date."
debug_echo "creating fnaify.dllmap.MidBoss.config from $gameconfig for MidBoss"
# copy $gameconfig to fnaify.dllmap.MidBoss.config
cp "$gameconfig" fnaify.dllmap.MidBoss.config
# edit fnaify.dllmap.MidBoss.config to use libSDL2_image_compact.so
sed -Ei 's/libSDL2_image\.so/libSDL2_image_compact.so/g' \
fnaify.dllmap.MidBoss.config
# redefine gameconfig to fnaify.dllmap.MidBoss.config
gameconfig=fnaify.dllmap.MidBoss.config
fi
;;
SSGame.exe )
mkdir -p ~/.local/share/SSDD
;;
esac
for f in $configbasearray; do
[ -e "$f" ] && { \
debug_echo "existing symlink target: ${f}.config -> $(readlink "${f}.config")"
gameconfigsymlink="${gameconfigsymlink}${f}.config "
[ "$gameconfig" = "$(readlink "${f}.config")" ] \
|| ln -sf "$gameconfig" "${f}.config"
}
done
gameconfigsymlink="${gameconfigsymlink}${my_exe}.config "
[ "$gameconfig" = "$(readlink "${my_exe}.config")" ] || \
ln -sf "$gameconfig" "${my_exe}.config"
# format all relevant command variables
depdir="$(echo "$depdir" | sed -E 's/:$//')"
monopath="$(echo "$monopath" | sed -E 's/:$//' | sed -E 's/^://')"
#########################################
# Heuristic for frameworkfile selection #
#########################################
# Scenario: user-specified framework file (-f)
if [ -n "$frameworkfile" ] ; then
debug_echo "using user-supplied frameworkfile: $frameworkfile"
# Scenario: MonoGame.Framework.dll
elif [ -f "$gamedir/MonoGame.Framework.dll" ] ; then
frameworkfile="$gamedir/MonoGame.Framework.dll"
# Scenario: user-specified framework version (-F)
elif [ -n "$frameworkversion" ] ; then
# check fnadir and gamedir for fitting version
if [ -f "$fnadir/FNA.dll" ] ; then
file_fwv="$(get_frameworkversion "$fnadir/FNA.dll")"
if [ "$(get_frameworkmajor "$file_fwv").$(get_frameworkminor "$file_fwv")" = "$(get_frameworkmajor "$frameworkversion").$(get_frameworkminor "$frameworkversion")" ] ; then
frameworkfile="$fnadir/FNA.dll"
fi
fi
if [ -z "$frameworkfile" ] && [ -f "$gamedir/FNA.dll" ] ; then
file_fwv="$(get_frameworkversion "$gamedir/FNA.dll")"
if [ "$(get_frameworkmajor "$file_fwv").$(get_frameworkminor "$file_fwv")" = "$(get_frameworkmajor "$frameworkversion").$(get_frameworkminor "$frameworkversion")" ] ; then
frameworkfile="$gamedir/FNA.dll"
fi
fi
if [ -z "$frameworkfile" ] ; then
install_fna "$frameworkversion"
frameworkfile="$gamedir/FNA.dll"
fi
# Scenario: no frameworkfile in gamedir
elif [ ! -f "$gamedir/FNA.dll" ] ; then
if [ -e "$gamedir/.fnaify_needfna" ] ; then
# this occurs if fnaify uses system framework file
if [ -f "$fnadir/FNA.dll" ] ; then
frameworkfile="$fnadir/FNA.dll"
else
echo "ERROR: frameworkfile needed, but not found. Try re-installing?"
exit
fi
else
debug_echo "game without framework file"
fi
# Scenario: FNA.dll in fnadir
elif [ -f "$fnadir/FNA.dll" ] ; then
# existence of $gamedir/FNA.dll is implied by above elif [ ! -f $gamedir/FNA.dll ]
debug_echo "by default, move FNA.dll out of gamedir if present in fnadir"
mkdir -p "$gamedir/fnaify-backup"
mv "$gamedir/FNA.dll" "$gamedir/fnaify-backup/"
debug_echo "touch .fnaify_needfna to make it clear framework file is needed"
touch "$gamedir/.fnaify_needfna"
frameworkfile="$fnadir/FNA.dll"
# Scenario: FNA.dll in gamedir - suboptimal for compatibility since mojoshader updates
else
# existence of $gamedir/FNA.dll implied by above
frameworkfile="$gamedir/FNA.dll"
fi
if [ -z "$frameworkversion" ] ; then
frameworkversion="$(get_frameworkversion "$frameworkfile")"
fi
datasize=$(( $(ulimit -d) / 1024 ))
echo
printdash "fnaify runtime configuration"
echo "fnaify Version: $FNAIFY_VERSION"
echo "Game Directory: $PWD" # PWD as cd'd into $gamedir happened above
echo "Mono Binary: $FNAIFY_MONO"
echo "Mono Path: $monopath"
echo "Main Assembly: $my_exe"
echo "Native Library Directories: $depdir"
echo "Framework File: $frameworkfile"
echo "Framework File Version: $frameworkversion"
echo "Symlinks to Config: $gameconfigsymlink"
echo "Config File: $gameconfig"
echo "Other Runtime Environment: $exe_env"
echo "Runtime Flags: $exe_flags $userflags"
echo "Datasize Limit: ${datasize} M"
echo
[ $datasize -lt 2048 ] && { \
echo "AT LEAST 2G are recommended for most games. See ksh(1) for ulimit command documentation"
echo
}
# check if broken symlinks exist in the game directory, e.g. libdl.so.2
IFS='
'
for l in $(find . -type l); do
IFS=$SAVEIFS
if [ ! -e "$l" ] ; then
newl="$(latest_syslib "$(trunklibnam "$(readlink "$l")")")"
if [ -z "$newl" ] ; then
echo "ERROR - broken symlink: $l. Expect trouble."
else
ln -fs "$newl" "$l"
fi
fi
done
debug_echo "env LD_LIBRARY_PATH=\"$depdir\" MONO_PATH=\"$monopath\" $exe_env \"$FNAIFY_MONO\" $debug \"$my_exe\" $exe_flags $userflags"
debug_echo ""
env LD_LIBRARY_PATH="$depdir" MONO_PATH="$monopath" $exe_env "$FNAIFY_MONO" $debug "$my_exe" $exe_flags $userflags
exit 0
}
setup()
{
echo "Performing setup (mode: $interaction) ..."
check_mono_binaries
check_eagle_island
cd "$gamedir" || exit 1
debug_echo "gamedir: $PWD" # cd'd into direct above
debug_echo "Setting up the framework files"
get_setup_frameworkfile
if [ -z "$setup_frameworkfile" ]; then
debug_echo "... no framework file found. Checking other options..."
else
debug_echo " framework file: $setup_frameworkfile"
setup_frameworkversion="$(get_frameworkversion "$setup_frameworkfile")"
debug_echo " framework version: $setup_frameworkversion"
fi
if [ -z "$setup_frameworkfile" ] ; then
# games without framework files:
# Atom Zombie Smasher, Eliza, Molek-Syntez, Exapunks, Opus Magnum (Lightning.exe),
# Shenzhen I/O, SpaceChem (64bit and fullscreen update from 2020-07-15), Streets of Fury EX
if [ -f "$gamedir/AtomZombieSmasher.exe" ] ; then
if ls $(echo "$depdir" | tr -s ':' ' ') | grep -q "libatomstb\.so"
then
debug_echo "\tfound libatomstb library in a library directory"
else
# add libatomstb to needlibarray
if [ "$(inarray libatomstb.so "$needlibarray")" = "false" ]
then
needlibarray[$((${#needlibarray[*]} + 1))]="$libatomstb.so"
debug_echo "\tlibatomstb.so added to array"
fi
fi
elif [ -f "$gamedir/Eliza.exe" ] \
|| [ -f "$gamedir/MOLEK-SYNTEZ.exe" ] \
|| [ -f "$gamedir/EXAPUNKS.exe" ] \
|| [ -f "$gamedir/Lightning.exe" ] \
|| [ -f "$gamedir/Shenzhen.exe" ] \
|| [ -f "$gamedir/SpaceChem.exe" ] \
|| [ -f "$gamedir/Hammerwatch.exe" ] \
|| [ -f "$gamedir/SOR4.exe" ] \
|| [ -f "$gamedir/MobiusFront83.exe" ] \
|| [ -f "$gamedir/Proteus.exe" ]
then
debug_echo "\nCompatible game without XNA/FNA framework file found."
debug_echo "Creating \$HOME/Desktop directory which is needed for Zachtronics games"
mkdir -p "$HOME/Desktop"
else
found_xna=0
IFS='
'
for f in $(find . -maxdepth 1 \( -iname "*.exe" -o -iname "*.dll" \) -exec file {} \; \
| grep -F "Mono/.Net assembly"); do
f="$(echo "$f" | cut -d : -f 1)"
debug_echo "Checking $f for XNA"
if ! $(monodis --assemblyref "$f" 2>&1 | grep -Fqim1 "Microsoft.Xna.Framework")
then
found_xna=1
break
fi
done
IFS=$SAVEIFS
if [ $found_xna -gt 0 ]; then
debug_echo "Found XNA reference"
xnasetup
else
echo "No FNA, MonoGame or XNA reference found"
exit 1
fi
fi
fi
if [ "$setup_frameworkfile" = "FNA.dll" ] && { [ "$frameworkmajor" -lt 16 ] || { [ "$frameworkmajor" -eq 16 ] && [ "$frameworkminor" -lt 5 ];};}
then
fna_warning=1
fi
check_nlog
set -A configfilesarray # empty the array
nconfigfilesarray=0 # TODO: is this really needed?
debug_echo "Identifying config files..."
IFS="
"
if [ -f "$gamedir"/*.config ]; then
for cfile in "$gamedir"/*.config; do
cfile="$(basename "$cfile")"
debug_echo " found config file: $cfile"
configfilesarray[$((${#configfilesarray[*]} + 1))]="$cfile"
nconfigfilesarray=$((nconfigfilesarray + 1))
done
fi
IFS=$SAVEIFS
debug_echo "Done identifying config files.\n"
if [ $nolibcheck -eq 1 ] ; then
debug_echo "skipping library checks"
else
# identify required libraries in .config files and lib{,64} directories
# TODO: filenames not whitespace-safe (but should not be used in such files anyway)
printdash "$(debug_echo "Identifying libraries required by the game...")"
#for MidBoss, add SDL2_image_compact to needlib
[ -f "$gamedir/MidBoss*" ] && \
needlibarray[$((${#needlibarray[*]} + 1))]="libSDL2_image_compact.so"
libraryname "lib64"
libraryname "lib"
libraryname "x64"
libraryname "x86"
debug_echo "\nChecking for library references in config files..."
if [ $nconfigfilesarray -lt 1 ]; then
debug_echo "...No config files found."
else
cfile=""
IFS="
"
for cfile in "${configfilesarray[@]}"; do
IFS=$SAVEIFS
debug_echo "\t$cfile"
linuxlines=$(grep "os\=\"linux" "$gamedir/$cfile") \
|| debug_echo "no os=linux entries in $cfile"
for libstring in $(echo "$linuxlines" | sed -n -E "s/.*target=\"([^\"]+).*/\1/p"); do
# Fix where library name includes directory information
libstring=$(echo "$libstring" | sed -E 's/^.\///')
# remove directories at the start of lib name
libstring=$(echo "$libstring" | sed -E 's/^.*\///')
debug_echo -n "\t\tFound library string: $libstring"
# sort out libs that need to be ignored
if [ "$(validlib "$libstring")" = "false" ]
then
debug_echo " - ignored"
continue
fi
libstring=$(trunklibnam "$libstring")
debug_echo -n " -> $libstring"
# add to libstring to needlibarray if not in there yet
case "$(inarray "$libstring" "$needlibarray")" in
"true")
debug_echo " - already in array"
;;
"false")
needlibarray[$((${#needlibarray[*]} + 1))]="$libstring"
debug_echo " - added to array"
;;
*)
printf '\n\t - ERROR: inarray returned with unexpected error\n\n'
exit 1
;;
esac
done
done
debug_echo "Done with identifying libraries in config files"
fi
debug_echo "Done with identification of needed libraries."
fi
debug_echo -n "\nChecking if libpng filename needs fixing..."
i=1
while [ "$i" -le "${#needlibarray[@]}" ]; do
needlibarray[i]="$(echo "${needlibarray[i]}" | sed -E "s/(libpng)..(\.so.*)/\1\2/")"
i=$((i + 1))
done
debug_echo " done.\n"
# Check if the libraries are available on the system (/usr/local/lib).
# If not, break and inform user which libraries need to be installed.
debug_echo "Checking installed libraries... "
# missinglibs[*] accumulates missing library names to inform user
missinglibs=""
for needlib in ${needlibarray}; do
if ls $(echo "$depdir" | tr -s ':' ' ') | grep -q "$needlib"
then
IFS=$SAVEIFS
debug_echo "\tfound library for: $needlib"
else
IFS=$SAVEIFS
debug_echo "\tNot found: $needlib"
missinglibs="$missinglibs$needlib "
fi
done
debug_echo "done.\n"
if [ -n "${missinglibs}" ]; then
printf '\nCould not find the following libraries:\n\n%b\n' "${missinglibs}"
exit 1
fi
# identify all .config files that do dllmap and move out of the way
debug_echo 'moving .config files with dllmap out of the way'
if [ ! -d "$gamedir/fnaify-backup" ] ; then
mkdir -p "$gamedir/fnaify-backup"
fi
IFS="
"
for config_file in "${configfilesarray[@]}"; do
IFS=$SAVEIFS
if [ ! -h "$config_file" ] && grep -q "dllmap" "$config_file"; then
mv "$config_file" "$gamedir/fnaify-backup/"
fi
done
debug_echo "Moving some bundled dll files into fnaify-backup subfolder... "
for file in $monofilearray; do
if [ -e "$gamedir/$file" ]; then
debug_echo "\tFound bundled mono file: $file"
mkdir -p "$gamedir/fnaify-backup"
mv "$gamedir/$file" "$gamedir/fnaify-backup/"
fi
done
debug_echo " done."
# if necessary, replace FNA.dll
fna_replace=""
lastdir=""
if [ $fna_warning -eq 1 ]; then
if [ "$interaction" = "i" ] ; then
printf '\nWARNING: version of FNA.dll potentially incompatble!\n'
echo "Fetch FNA 17.12 from GitHub, compile, and replace bundled FNA.dll?"
echo "FNA is distributed under Microsoft Public License. The license"
echo "can be viewed here:"
echo "https://github.com/FNA-XNA/FNA/blob/master/licenses/LICENSE"
echo -n "Proceed with replacing FNA with version 17.12 (recommended)? [y/n] "
until [ "$fna_replace" = "y" ] || [ "$fna_replace" = "n" ]; do
read -r fna_replace
done
elif [ "$interaction" = "y" ] ; then
fna_replace="y"
else
fna_replace="n"
fi
if [ "$fna_replace" = "y" ]; then
install_fna 17.12
fna_warning=0
fi
fi
symlink_mg_libs
iomap
if [ -n "${licenses}" ]; then
printf 'Installed modules are under the following license(s):\n\n'
echo "${licenses}"
fi
if [ $fna_warning -eq 1 ]; then
printf '\nWARNING: version of FNA.dll potentially incompatible!\n'
printf "If the game doesn't run, try running 'fnaify -i' (or 'fnaify -y').\n\n"
fi
if [ $nlog_warning -eq 1 ]; then
printf '\nWARNING: version of NLog.dll potentially incompatible!\n'
printf "If the game doesn't run, try running 'fnaify -i' (or 'fnaify -y').\n\n"
fi
touch .fnaify_ready
}
### END OF VARIABLES AND FUNCTIONS ###
###################
### MAIN ###
###################
process_options "$@"
if [ $force_setup -gt 0 ]
then
setup
run
else
[ ! -e "$gamedir/.fnaify_ready" ] && setup
run
fi