#!/usr/bin/env bash
# -*- coding: utf-8 -*-
###########################################################################
# #
# run-fgfs - a wrapper to run FlightGear #
# Copyright (C) 2007 Arvid Norlander #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###########################################################################
##########################################################
# Config section - most can be overriden by command line #
##########################################################
# Default fg version. (can be either plib or osg)
FG_VERSION=plib
# Connect to MP by default? (can be 0 or 1)
FG_MP=1
# Enable fuel freeze by default? (can be 0 or 1)
FG_FUEL_FREEZE=1
# Enable real weather fetch by default? (can be 0 or 1)
FG_WEATHER=0
# Enable auto coordination by default? (can be 0 or 1)
FG_AUTO_COORD=0
# Enable traffic manager by default? (can be 0 or 1)
# Note: traffic manager is known to slow down flightgear
# and cause other problems
FG_TRAFFIC_MANAGER=0
# Enable using of festival to speak messages? (can be 0 or 1)
FG_VOICE=1
# Enable "game mode" by default? (can be 0 or 1)
FG_GAME_MODE=0
# If non-empty the -atc option will set this callsign (for MP)
FG_ATC_CALLSIGN="KSFO"
# For MP: Local mp connection setting.
# Format: ip,port
# IP should be IP that exists on LOCAL computer (not your router outside one).
FG_MP_LOCAL="192.168.0.1,5000"
# For MP: Remote mp connection setting.
# Format: host,port
# Host can be either a hostname or IP
FG_MP_REMOTE="mpserver02.flightgear.org,5000"
# Path to FG/PLIB build root directory
FG_PLIB_PATH="$HOME/src/external/flightgear/source"
# Path to FG/OSG build root directory
FG_OSG_PATH="$HOME/src/external/flightgear/source-head"
# If non-empty this will set a LD_LIBRARY_PATH for fg/plib:
FG_PLIB_LDPATH=""
# If non-empty this will set a LD_LIBRARY_PATH for fg/osg:
FG_OSG_LDPATH="$HOME/local/flightgear-osg/lib"
# For -loc, where are the files stored:
FG_LOC_PATH="$HOME/share/run-fg/locations"
###############################
# Don't edit stuff after this #
###############################
# Check for new enough bash version
fail_old_bash() {
echo "Sorry your bash version is too old!"
echo "You need at least version 3.1 of bash."
echo "Please install a newer version:"
echo " * Either use your distro's packages."
echo " * Or see http://www.gnu.org/software/bash/"
exit 2
}
# Check bash version. We need at least 3.1
# Lets not use anything like =~ here because
# that may not work on old bash versions.
if [[ "${BASH_VERSINFO[0]}${BASH_VERSINFO[1]}" -lt 31 ]]; then
fail_old_bash
fi
# Set up some stuff to help with debugging the script
set +amu
set -f
shopt -u sourcepath hostcomplete progcomp xpg_echo dotglob
shopt -u nocasematch nocaseglob nullglob
shopt -s extquote promptvars extglob extdebug
export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]} : '
################################################################################
# Set the variable in $2 to the terminal cap $1
# WARNING: Use this function ONLY for string caps!
# Parameters:
# 1 string capname
# 2 string Return variable name (Use Ind. ref.)
# Exit code:
# 0=OK
# 1=Not sup. or unknown cap
check_cap() {
tput $1 &>/dev/null
if [[ $? -eq 0 ]]; then
printf -v "$2" '%s' "$(tput $1)"
return 0
else
printf -v "$2" '%s' ''
return 1
fi
}
################################################################################
check_cap bold tBOLD
check_cap smul tbUNDERLINE
check_cap rmul teUNDERLINE
check_cap bel tBELL
check_cap sgr0 tSTD
check_cap 'setaf 0' tcBLACK
check_cap 'setaf 1' tcRED
check_cap 'setaf 2' tcGREEN
check_cap 'setaf 3' tcYELLOW
check_cap 'setaf 4' tcBLUE
check_cap 'setaf 5' tcMAGENTA
check_cap 'setaf 6' tcCYAN
check_cap 'setaf 7' tcWHITE
print_negative_message() {
echo "${tcRED}${1}${tSTD}"
}
################################################################################
# Aborts program with message
# Parameters:
# 1 string Message
# 2 string Exit status
# Returns:
# Does not return
do_abort() {
print_negative_message "${tcRED}Error:${tSTD} ${1}"
print_negative_message 'Aborting'
exit $2
}
################################################################################
################################################################################
# Shows message about missing argument(s) and exits with status 1.
# Parameters:
# 1 string Name of option missing an argument(s)
# 2 integer Optional: Number of arguments Std=1
# Returns:
# Does not return
missing_arg() {
if [[ $2 ]]; then
do_abort "${1} requires ${2} arguments" 1
else
do_abort "${1} requires an argument" 1
fi
}
################################################################################
PRINT_version() {
cat <<- EOF
run-fgfs 0.0.2 - A wrapper for starting FlightGear
Copyright (C) 2007 Arvid Norlander
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Arvid Norlander.
EOF
exit 0
}
PRINT_Help() {
cat <<- EOF
run-fgfs is a wrapper for starting FlightGear
Usage: run-fgfs [OPTIONS]...
Main options:
-help Show this help
-version Show version
-osg Run osg.
-plib Run plib.
Feature options:
-ac Auto-coordination.
-no-ac No auto-coordination.
-ff Fuel freeze.
-no-ff No fuel freeze.
-gm Enable "game mode".
-no-gm Disable "game mode".
-mp Multiplayer.
-no-mp No multiplayer.
-tm Traffic manager.
-no-tm No traffic manager.
-w Real weather fetch.
-no-w No real weather fetch.
Other Options:
-loc x Start at saved location x.
-atc Start an ATC setup (may not work for you).
All parameters except those prefixed with one dash (-)
are passed directly to flightgear.
Defaults for most options can be set in the beginning of the script.
Also path to flightgear MUST be set there.
EOF
if [[ "$1" ]]; then
exit $1
else
exit 0
fi
}
FG_ATC=0
# Stuff passed on command line that we don't handle ourself.
FG_UNK_ARGS=()
FG_LOC=""
if [[ $# -gt 0 ]]; then # there are arguments to the command
while [[ $# -gt 0 ]]; do
case "$1" in
'-help'|'-usage'|'-h'|'')
PRINT_Help
;;
'-version')
PRINT_version
;;
'-osg')
FG_VERSION='osg'
shift 1
;;
'-plib')
FG_VERSION='plib'
shift 1
;;
'-mp')
FG_MP=1
shift 1
;;
'-no-mp')
FG_MP=0
shift 1
;;
'-ff')
FG_FUEL_FREEZE=1
shift 1
;;
'-no-ff')
FG_FUEL_FREEZE=0
shift 1
;;
'-ac')
FG_AUTO_COORD=1
shift 1
;;
'-no-ac')
FG_AUTO_COORD=0
shift 1
;;
'-gm')
FG_GAME_MODE=1
shift 1
;;
'-no-gm')
FG_GAME_MODE=0
shift 1
;;
'-tm')
FG_TRAFFIC_MANAGER=1
shift 1
;;
'-no-tm')
FG_TRAFFIC_MANAGER=0
shift 1
;;
'-w')
FG_WEATHER=1
shift 1
;;
'-no-w')
FG_WEATHER=0
shift 1
;;
'-atc')
FG_ATC=1
shift 1
;;
'-loc')
if [[ "$2" ]]; then
FG_LOC="$2"
shift 2
else
missing_arg "$1"
fi
;;
# Two --? To fg
'--'*)
FG_UNK_ARGS+=( "$1" )
shift 1
;;
# One -? To us
'-'*)
PRINT_Help
;;
# Other? To fg
*)
FG_UNK_ARGS+=( "$1" )
shift 1
;;
esac
done
else
PRINT_Help 1
fi
# Array for constructed arguments
FG_ARGS=()
if [[ "$FG_ATC" -eq 1 ]]; then
FG_MP=1
FG_FUEL_FREEZE=0
FG_AUTO_COORD=0
FG_WEATHER=1
FG_TRAFFIC_MANAGER=0
FG_LOC=""
FG_VERSION='osg'
FG_ARGS+=( "--aircraft=ATC" )
if [[ $FG_ATC_CALLSIGN ]]; then
FG_ARGS+=( "--callsign=$FG_ATC_CALLSIGN" )
fi
fi
if [[ "$FG_MP" -eq 1 ]]; then
FG_ARGS+=( "--multiplay=out,10,$FG_MP_REMOTE" "--multiplay=in,10,$FG_MP_LOCAL" )
fi
if [[ "$FG_FUEL_FREEZE" -eq 1 ]]; then
FG_ARGS+=( "--enable-fuel-freeze" )
else
FG_ARGS+=( "--disable-fuel-freeze" )
fi
if [[ "$FG_AUTO_COORD" -eq 1 ]]; then
FG_ARGS+=( "--enable-auto-coordination" )
else
FG_ARGS+=( "--disable-auto-coordination" )
fi
if [[ "$FG_WEATHER" -eq 1 ]]; then
FG_ARGS+=( "--enable-real-weather-fetch" )
else
FG_ARGS+=( "--disable-real-weather-fetch" )
fi
if [[ "$FG_GAME_MODE" -eq 1 ]]; then
FG_ARGS+=( "--enable-game-mode" )
else
FG_ARGS+=( "--disable-game-mode" )
fi
if [[ "$FG_TRAFFIC_MANAGER" -eq 1 ]]; then
FG_ARGS+=( "--prop:sim/traffic-manager/enabled=1" )
else
FG_ARGS+=( "--prop:sim/traffic-manager/enabled=0" )
fi
if [[ "$FG_VOICE" -eq 1 ]]; then
FG_ARGS+=( "--prop:/sim/sound/voices/enabled=true" )
else
FG_ARGS+=( "--prop:/sim/sound/voices/enabled=false" )
fi
# Handle -loc
if [[ $FG_LOC ]]; then
if [[ -z $FG_LOC_PATH ]]; then
do_abort "FG_LOC_PATH is not set, please fix this." 1
fi
if [[ ! -d $FG_LOC_PATH ]]; then
do_abort "FG_LOC_PATH \"$FG_LOC_PATH\" is not an existing directory (check that it is there and check permissions)." 1
fi
if [[ -f "${FG_LOC_PATH}/${FG_LOC}" ]]; then
source "${FG_LOC_PATH}/${FG_LOC}"
FG_ARGS+=( "--lon=$FG_LON" "--lat=$FG_LAT" "--altitude=$FG_ALT" "--heading=$FG_HEADING" "--roll=$FG_ROLL" "--pitch=$FG_PITCH" )
else
do_abort "${FG_LOC} does not exist" 1
fi
fi
if [[ "$FG_VERSION" = "plib" ]]; then
targetdir="$FG_PLIB_PATH/src/Main"
target_type=PLIB
else
targetdir="$FG_OSG_PATH/src/Main"
target_type=OSG
fi
if [[ -d "$targetdir" ]]; then
cd "$targetdir"
else
do_abort "$targetdir does not exist... FG_${target_type}_PATH is not a valid build tree..."
fi
echo "Final command line: ${FG_ARGS[*]} ${FG_UNK_ARGS[*]}"
echo "Preparing to run flightgear..."
# Prepare to run fg
if [[ "$FG_VERSION" = "plib" ]]; then
if [[ $FG_PLIB_LDPATH ]]; then
export LD_LIBRARY_PATH="$FG_PLIB_LDPATH"
fi
./fgfs "${FG_ARGS[@]}" "${FG_UNK_ARGS[@]}"
elif [[ "$FG_VERSION" = "osg" ]]; then
cd "$FG_OSG_PATH/src/Main"
if [[ $FG_OSG_LDPATH ]]; then
export LD_LIBRARY_PATH="$FG_OSG_LDPATH"
fi
./fgfs "${FG_ARGS[@]}" "${FG_UNK_ARGS[@]}"
fi
exit 0