#!/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 . # # # ########################################################################### ########################################################## # 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