searchandrescue_1.7.0/0000755000175000001440000000000013452220522013765 5ustar jesseuserssearchandrescue_1.7.0/distclean0000664000175000001440000000022112046776371015673 0ustar jesseusers#!/bin/sh echo "Cleaning for distribution..." chmod 755 include make clean ./configure --reset echo "Tree has been cleaned for distribution." searchandrescue_1.7.0/control0000664000175000001440000000357412046776371015423 0ustar jesseusersSource: searchandrescue Section: games Priority: extra Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Phil Brooke Build-Depends: debhelper (>= 4), liby-dev (>= 2.14.2-2), libx11-dev, libxext-dev, libxpm-dev, libxxf86vm-dev, sharutils, bzip2, libsm-dev, libxmu-dev, libglu1-mesa-dev Standards-Version: 3.8.0 Homepage: http://wolfpack.twu.net/SearchAndRescue/ Package: searchandrescue Architecture: any Depends: ${shlibs:Depends}, searchandrescue-common (= ${source:Version}), searchandrescue-data (>= 0.8.2-1) Recommends: yiff-server Conflicts: sar Replaces: sar Description: fly aircraft to search (for) and rescue people in distress Tired of scores indicating things destroyed or lives snuffed? Try something different -- fly a helicopter around and rescue people in distress. If you were in trouble wouldn't you want someone to rescue you? . This game is intended for players of all audiences, but especially for mature players who want to get away from the violence and still retain a level of precise challenge. Flight difficulty can be lowered for beginners (regardless of mission type), and graphics minimized to suit slower computers (minimum Pentium 166 with no graphics acceleration). . This package has been configured to depend on libY2 for sound support. However, sound support is not necessary to enjoy the game. (See README.Debian for more information.) Package: searchandrescue-common Architecture: all Conflicts: sar, searchandrescue (<< 0.7.20-7) Description: common files and documentation for searchandrescue Tired of scores indicating things destroyed or lives snuffed? Try something different -- fly a helicopter around and rescue people in distress. If you were in trouble wouldn't you want someone to rescue you? . This package contains the documentation and architecture independent (common) files. searchandrescue_1.7.0/installsardata0000664000175000001440000000370313452162060016725 0ustar jesseusers#!/bin/bash # This installsardata script: # 1) Verifies the latest SearchAndRescue datafile or a link to it is # located in the current directory # 2) Checks whether it has been run with root privileges # 3) Verifies the datafile is not corrupted # 4) Creates the data installation directory if it doesn't exist # 5) Deletes old datafiles if there are any # 6) Installs the latest datafiles #Definitions # !!! Update line below for each new data file release !!! sar_datafile=SearchAndRescue-data-1.6.1.tar.gz sar_data_install_dir="/usr/share/games/searchandrescue" sar_data_source_directory="" # Check SearchAndRescue Datafile is in local directory if !([ -f $sar_datafile ]) then echo "Please check that $sar_datafile or a link to it is in the current directory" exit 2 fi # Verify SearchAndRescue datafile is not corrupted if !( tar tzf $sar_datafile &>/dev/null ) then echo "$sar_datafile is corrupted, please get another copy and re-run this script" exit 3 fi # Have we been invoked with root privileges? eval `id | sed 's/[^a-z0-9=].*//'` if [ "${uid:=0}" -ne 0 ] then echo "Data installation requires root privileges. For Debian based distros (e.g. Ubuntu), use sudo $0 ." echo "For other distros, type su , then $0 ." exit 4 fi #Remember current directory sar_data_source_directory=`pwd` # Check if there is already a SearchAndRescue datafile directory and if so, delete all contents # Otherwise, create the directory if [ -d $sar_data_install_dir ] then rm -fr $sar_data_install_dir/* >/dev/null echo "Old Datafiles deleted in $sar_data_install_dir" else mkdir -p $sar_data_install_dir fi #Extract datafile to the final location and report success or otherwise cd $sar_data_install_dir if ( tar xzf $sar_data_source_directory/$sar_datafile &>/dev/null ) then echo "$sar_datafile successfully extracted to $sar_data_install_dir" else echo "Error extracting $sar_datafile to $sar_data_install_dir" fi searchandrescue_1.7.0/prerm0000664000175000001440000000210212046776371015052 0ustar jesseusers#! /bin/bash # prerm script for searchandrescue # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `remove' # * `upgrade' # * `failed-upgrade' # * `remove' `in-favour' # * `deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in remove|upgrade|deconfigure) # install-info --quiet --remove /usr/info/#PACKAGE#.info.gz ;; failed-upgrade) ;; *) echo "prerm called with unknown argument \`$1'" >&2 exit 1 ;; esac if [ \( "$1" = "upgrade" -o "$1" = "remove" \) -a -L /usr/doc/searchandrescue ]; then rm -f /usr/doc/searchandrescue fi # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 searchandrescue_1.7.0/AUTHORS0000664000175000001440000000037312046776370015061 0ustar jesseusershttp://wolfpack.twu.net/contacts.html Since the WolfPack website seems to be off-line, you can get a list of the original authors from the copyright file in this directory. The new project page can be found at http://searchandrescue.sourceforge.net searchandrescue_1.7.0/postinst0000664000175000001440000000241612046776371015620 0ustar jesseusers#! /bin/sh # postinst script for searchandrescue # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package # # quoting from the policy: # Any necessary prompting should almost always be confined to the # post-installation script, and should be protected with a conditional # so that unnecessary prompting doesn't happen if a package's # installation fails and the `postinst' is called with `abort-upgrade', # `abort-remove' or `abort-deconfigure'. case "$1" in configure) ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 searchandrescue_1.7.0/copyright0000664000175000001440000000113012046776371015735 0ustar jesseusersThis package was debianized by David Kimdon on Sat, 14 Oct 2000 23:16:15 -0700. It was downloaded from http://wolfpack.twu.net/ Upstream Authors: WolfPack Entertainment, Joel Baker (aka BlackJaguar) lucifer@lightbearer.com Tara Milana Stefan Maron Marcus Kudsen Dan Stimits This software is Copyright (C) 1999-2004 WolfPack Entertainment You are free to distribute this software under the terms of the GNU General Public License. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL file. searchandrescue_1.7.0/rules0000664000175000001440000000537212046776370015072 0ustar jesseusers#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 DOCDIR=`pwd`/debian/searchandrescue/usr/share/doc/searchandrescue/html/ configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. ./configure Linux touch configure-stamp build: configure-stamp build-stamp build-stamp: dh_testdir # Add here commands to compile the package. $(MAKE) touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. [ ! -f Makefile ] || $(MAKE) clean -rm -f sar/SearchAndRescue -rm -f pconf/pconf -rm -f sar/Makefile -rm -f sar/this_platform.ini dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/tmp. $(MAKE) install DESTDIR=`pwd`/debian/searchandrescue # mkdir -p $(DOCDIR) # install -m 0444 docs/*.png docs/*.html $(DOCDIR) # Create directory .../debian/searchandrescue-common. install -d -g root -m 755 -o root `pwd`/debian/searchandrescue-common/usr/share # Move common files. # mv `pwd`/debian/searchandrescue/usr/share/doc `pwd`/debian/searchandrescue-common/usr/share mv `pwd`/debian/searchandrescue/usr/X11R6/include/X11/pixmaps `pwd`/debian/searchandrescue-common/usr/share rm -r `pwd`/debian/searchandrescue/usr/X11R6 # Desktop file install -d -g root -m 755 -o root `pwd`/debian/searchandrescue/usr/share/applications install -m 644 debian/SearchAndRescue.desktop `pwd`/debian/searchandrescue/usr/share/applications/SearchAndRescue.desktop # Lintian overrides install -d -g root -m 755 -o root `pwd`/debian/searchandrescue/usr/share/lintian/overrides install -m 644 debian/lintian-overrides.searchandrescue \ `pwd`/debian/searchandrescue/usr/share/lintian/overrides/searchandrescue # Un-bzip the manpage. bunzip2 `pwd`/debian/searchandrescue/usr/share/man/man6/SearchAndRescue.6.bz2 # Build architecture-independent files here. binary-indep: build install dh_testdir -i dh_testroot -i dh_installdocs -i dh_installmenu -i # dh_installmanpages -i dh_desktop dh_installchangelogs -i dh_strip -i dh_compress -i dh_fixperms -i dh_installdeb -i dh_shlibdeps -i dh_gencontrol -i dh_md5sums -i dh_builddeb -i # Build architecture-dependent files here. binary-arch: build install dh_testdir -a dh_testroot -a dh_installdocs -a dh_installmenu -a # dh_installmanpages -a dh_desktop dh_installchangelogs -a dh_strip -a dh_compress -a dh_fixperms -a dh_installdeb -a dh_shlibdeps -a dh_gencontrol -a dh_md5sums -a dh_builddeb -a binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure searchandrescue_1.7.0/SearchAndRescue.xpm0000664000175000001440000007756012046776371017553 0ustar jesseusers/* XPM */ static char * SearchAndRescue_xpm[] = { "48 48 1735 2", " c None", ". c #558CB0", "+ c #4D85A9", "@ c #558AAF", "# c #598DB3", "$ c #5287AD", "% c #5489AE", "& c #5A92B5", "* c #538AAE", "= c #5D94B7", "- c #5F94B8", "; c #6B9FC4", "> c #5C90B5", ", c #5E92B5", "' c #5D91B4", ") c #5C90B3", "! c #5E92B6", "~ c #5C90B4", "{ c #5789AE", "] c #6095B6", "^ c #5E93B3", "/ c #5C90B1", "( c #6093B4", "_ c #5B8EAE", ": c #5C8FB0", "< c #5E91B2", "[ c #6394B5", "} c #6B9CBD", "| c #6697B9", "1 c #6B9BBC", "2 c #6B9CBE", "3 c #6397B7", "4 c #689CBC", "5 c #679BBA", "6 c #669ABA", "7 c #6C9DBE", "8 c #6A99BB", "9 c #6D9DBD", "0 c #73A2C2", "a c #6F9EBC", "b c #6C9CB7", "c c #72A2BD", "d c #72A4BE", "e c #6FA0BC", "f c #72A3BE", "g c #73A2BE", "h c #4A81A7", "i c #4F87AD", "j c #5D94BB", "k c #4F86AC", "l c #538AB0", "m c #5289AF", "n c #4D84A9", "o c #5188AD", "p c #588EB3", "q c #4F85AA", "r c #5B93B7", "s c #4F86AB", "t c #528AAE", "u c #5B91B6", "v c #5A90B5", "w c #5E94B9", "x c #558DAF", "y c #5991B2", "z c #5F97B8", "A c #578FAF", "B c #659CBD", "C c #5D94B4", "D c #5A91B1", "E c #6195B6", "F c #699DBE", "G c #588CAE", "H c #5D91B2", "I c #5E92B3", "J c #5B94B7", "K c #5891B4", "L c #5790B3", "M c #5E97BA", "N c #5A93B6", "O c #5F93B9", "P c #6293BA", "Q c #6192B8", "R c #5E90B4", "S c #75A6C8", "T c #699CBC", "U c #6295B5", "V c #649CB9", "W c #649BB7", "X c #639AB7", "Y c #669DB9", "Z c #5087AE", "` c #4F85AD", " . c #4F85AB", ".. c #578DB2", "+. c #548AB1", "@. c #4D83A9", "#. c #5189AD", "$. c #5289AE", "%. c #4E85AA", "&. c #5087AD", "*. c #4981A4", "=. c #4C84A7", "-. c #5289AB", ";. c #4A81A4", ">. c #5087A9", ",. c #4E85A7", "'. c #548CAE", "). c #558CAE", "!. c #5187A9", "~. c #4F85A7", "{. c #4F85A8", "]. c #5187AC", "^. c #4F85A9", "/. c #548AAE", "(. c #6299BD", "_. c #5E95B9", ":. c #5F95B9", "<. c #6094BA", "[. c #6092B9", "}. c #5F91B8", "|. c #689ABC", "1. c #6092B2", "2. c #6093B2", "3. c #5E95B5", "4. c #5F96B7", "5. c #6198B9", "6. c #6298B9", "7. c #447CA2", "8. c #4981A8", "9. c #4D84AB", "0. c #4A82A9", "a. c #477DA4", "b. c #42799F", "c. c #487FA5", "d. c #4C82A9", "e. c #477DA3", "f. c #4B81A7", "g. c #598FB5", "h. c #4981A6", "i. c #4B84A9", "j. c #4880A6", "k. c #4880A5", "l. c #4C84A9", "m. c #4F87AC", "n. c #4982A5", "o. c #4B85A8", "p. c #528BAE", "q. c #5D96B9", "r. c #538CAF", "s. c #4C86A9", "t. c #4A80A4", "u. c #457B9F", "v. c #4F84A9", "w. c #4A7FA4", "x. c #477BA1", "y. c #4C7EA2", "z. c #4F81A5", "A. c #4D7FA3", "B. c #5183A7", "C. c #5C8EB2", "D. c #5689AE", "E. c #5689AD", "F. c #5487AB", "G. c #5588AA", "H. c #5386A6", "I. c #5C90AE", "J. c #5488A6", "K. c #5B91B3", "L. c #558BAE", "M. c #5B91B4", "N. c #5A8FB2", "O. c #427CA2", "P. c #4D85AC", "Q. c #4780A7", "R. c #437CA3", "S. c #467FA6", "T. c #467EA4", "U. c #467DA3", "V. c #4379A0", "W. c #3A7097", "X. c #3F749B", "Y. c #477BA3", "Z. c #497DA4", "`. c #4A82A7", " + c #467CA2", ".+ c #4C82A8", "++ c #457BA1", "@+ c #487FA4", "#+ c #477FA3", "$+ c #467DA1", "%+ c #497EA3", "&+ c #4B81A6", "*+ c #467CA0", "=+ c #4980A4", "-+ c #447A9F", ";+ c #477EA2", ">+ c #4C80A5", ",+ c #4C7FA5", "'+ c #4D81A7", ")+ c #4E81A6", "!+ c #598CB2", "~+ c #598CB0", "{+ c #5183A9", "]+ c #4A7CA2", "^+ c #4F84A7", "/+ c #4B81A3", "(+ c #4A80A2", "_+ c #4B81A1", ":+ c #4E82A2", "<+ c #5185A5", "[+ c #4E81A2", "}+ c #5388AA", "|+ c #5489AB", "1+ c #5186A9", "2+ c #4D80A3", "3+ c #4079A0", "4+ c #4A83AA", "5+ c #3E769D", "6+ c #397097", "7+ c #4178A0", "8+ c #3C739A", "9+ c #396E96", "0+ c #40759C", "a+ c #3D7399", "b+ c #3B6E95", "c+ c #43769D", "d+ c #3B6D94", "e+ c #477CA2", "f+ c #4B7FA6", "g+ c #487CA3", "h+ c #40739A", "i+ c #376A91", "j+ c #3E7299", "k+ c #437AA0", "l+ c #44789F", "m+ c #41739B", "n+ c #477AA1", "o+ c #4F81A9", "p+ c #4D82A8", "q+ c #4B80A7", "r+ c #4E83A9", "s+ c #487AA2", "t+ c #4B7DA5", "u+ c #487DA4", "v+ c #457AA1", "w+ c #497EA5", "x+ c #4F84AA", "y+ c #4A7FA6", "z+ c #4F84AB", "A+ c #4E83A7", "B+ c #467B9D", "C+ c #487D9E", "D+ c #5488AA", "E+ c #5D8FB1", "F+ c #4B7EA0", "G+ c #5486A8", "H+ c #4B7FA1", "I+ c #558AAC", "J+ c #4F84A6", "K+ c #5688AA", "L+ c #336B92", "M+ c #356D94", "N+ c #386F96", "O+ c #3D749C", "P+ c #40779E", "Q+ c #376E95", "R+ c #42779E", "S+ c #3D7299", "T+ c #40739B", "U+ c #4D80A7", "V+ c #44779E", "W+ c #497EA4", "X+ c #43779E", "Y+ c #42759C", "Z+ c #376B92", "`+ c #40759B", " @ c #42779D", ".@ c #487CA4", "+@ c #45779F", "@@ c #45789F", "#@ c #4479A0", "$@ c #43759D", "%@ c #467CA3", "&@ c #3F759B", "*@ c #4E83AA", "=@ c #A2300F", "-@ c #A13110", ";@ c #4E84A7", ">@ c #4D83A6", ",@ c #4F82A6", "'@ c #578AAE", ")@ c #5487AA", "!@ c #477C9F", "~@ c #679CBF", "{@ c #6092B6", "]@ c #366D95", "^@ c #3C7299", "/@ c #3D739A", "(@ c #3F759D", "_@ c #41789F", ":@ c #4A80A8", "<@ c #497FA7", "[@ c #346A92", "}@ c #568CB3", "|@ c #477AA2", "1@ c #41769C", "2@ c #497CA3", "3@ c #3E7198", "4@ c #44779F", "5@ c #497FA5", "6@ c #4E84AA", "7@ c #467BA1", "8@ c #477BA2", "9@ c #447AA0", "0@ c #4A80A6", "a@ c #3F7199", "b@ c #4679A0", "c@ c #42789E", "d@ c #4B81A8", "e@ c #4D83AA", "f@ c #4A80A3", "g@ c #41779A", "h@ c #4B80A3", "i@ c #6C9FC5", "j@ c #5083A9", "k@ c #4D7FA5", "l@ c #5288AB", "m@ c #4C82A5", "n@ c #548AAD", "o@ c #5284AA", "p@ c #3C729A", "q@ c #3B7099", "r@ c #346990", "s@ c #32668E", "t@ c #3D729B", "u@ c #3D719A", "v@ c #366D94", "w@ c #3D739B", "x@ c #396F96", "y@ c #3F759C", "z@ c #3E749B", "A@ c #376D94", "B@ c #3A7096", "C@ c #376C93", "D@ c #42789F", "E@ c #3E749A", "F@ c #32688E", "G@ c #40769D", "H@ c #3B7197", "I@ c #3C7298", "J@ c #457CA2", "K@ c #447AA1", "L@ c #487EA5", "M@ c #4B80A6", "N@ c #4D83A8", "O@ c #41779C", "P@ c #40769C", "Q@ c #477DA2", "R@ c #4A80A5", "S@ c #43789D", "T@ c #6295BE", "U@ c #4C7EA7", "V@ c #5385AE", "W@ c #4678A1", "X@ c #4477A1", "Y@ c #40739D", "Z@ c #396F97", "`@ c #346B91", " # c #396F95", ".# c #41789E", "+# c #41779D", "@# c #41779E", "## c #3A7197", "$# c #3F769C", "%# c #477EA4", "&# c #3E759B", "*# c #3D749A", "=# c #386E94", "-# c #386D94", ";# c #3C7399", "># c #A32E13", ",# c #9B3518", "'# c #43799F", ")# c #346A8F", "!# c #33698F", "~# c #396E94", "{# c #396C95", "]# c #31638C", "^# c #396B94", "/# c #3B6D96", "(# c #3E719A", "_# c #41739D", ":# c #376E96", "<# c #386E96", "[# c #3E749C", "}# c #3A7098", "|# c #386E95", "1# c #32688F", "2# c #3E759C", "3# c #3A7198", "4# c #356B92", "5# c #3D7298", "6# c #3A6F96", "7# c #651F0D", "8# c #8C4131", "9# c #43789E", "0# c #487DA3", "a# c #4479A1", "b# c #4379A1", "c# c #3C7199", "d# c #3C7297", "e# c #356C93", "f# c #32668F", "g# c #31658D", "h# c #40759E", "i# c #3F749D", "j# c #40749C", "k# c #3A6D96", "l# c #4279A1", "m# c #356C94", "n# c #386F98", "o# c #376E97", "p# c #376D96", "q# c #356891", "r# c #356790", "s# c #36678F", "t# c #3B6C94", "u# c #3A6C94", "v# c #40719A", "w# c #3C709C", "x# c #3D729D", "y# c #3D729A", "z# c #386D95", "A# c #44799F", "B# c #3F7399", "C# c #3B7098", "D# c #3E729A", "E# c #A23011", "F# c #A13010", "G# c #35658D", "H# c #47779F", "I# c #4E7FA7", "J# c #43749C", "K# c #4878A0", "L# c #4B7BA3", "M# c #3C7198", "N# c #457AA0", "O# c #4A7CA3", "P# c #3B7299", "Q# c #30658D", "R# c #30648C", "S# c #396F98", "T# c #376C95", "U# c #326991", "V# c #397098", "W# c #326990", "X# c #356991", "Y# c #386C95", "Z# c #31668F", "`# c #326890", " $ c #336891", ".$ c #4A7FA7", "+$ c #3A6E97", "@$ c #2F618A", "#$ c #34648D", "$$ c #33638C", "%$ c #3C6C95", "&$ c #43739C", "*$ c #4A7AA3", "=$ c #4578A3", "-$ c #3F719B", ";$ c #3D7198", ">$ c #3A6D94", ",$ c #3D7196", "'$ c #316388", ")$ c #34678E", "!$ c #396C93", "~$ c #3B6F96", "{$ c #396C94", "]$ c #386B92", "^$ c #B63A1B", "/$ c #AE3414", "($ c #3B6B93", "_$ c #3E6E96", ":$ c #417199", "<$ c #386991", "[$ c #396991", "}$ c #3D6D95", "|$ c #34688E", "1$ c #396D94", "2$ c #3C7097", "3$ c #3D6E96", "4$ c #316990", "5$ c #2F648D", "6$ c #2F648C", "7$ c #41759D", "8$ c #336990", "9$ c #336A91", "0$ c #33668F", "a$ c #386C94", "b$ c #366A91", "c$ c #3E7098", "d$ c #41729B", "e$ c #396B93", "f$ c #35678F", "g$ c #3A6B94", "h$ c #4A7BA4", "i$ c #4B7EA7", "j$ c #4A7CA4", "k$ c #497BA2", "l$ c #6094B7", "m$ c #5386A9", "n$ c #386A91", "o$ c #33668D", "p$ c #34668D", "q$ c #5385AC", "r$ c #D33D23", "s$ c #AE857F", "t$ c #2F6088", "u$ c #33648D", "v$ c #407199", "w$ c #356A91", "x$ c #356990", "y$ c #3A6E95", "z$ c #366890", "A$ c #2D638B", "B$ c #387097", "C$ c #3F769D", "D$ c #437AA1", "E$ c #3E7196", "F$ c #3D6F94", "G$ c #407398", "H$ c #42759A", "I$ c #376A8F", "J$ c #3D7097", "K$ c #3D7098", "L$ c #356890", "M$ c #3C6F97", "N$ c #34678F", "O$ c #41749C", "P$ c #4A7DA5", "Q$ c #3D6E97", "R$ c #43749A", "S$ c #396A8F", "T$ c #396B8E", "U$ c #316485", "V$ c #326489", "W$ c #336489", "X$ c #36678C", "Y$ c #326389", "Z$ c #FF9886", "`$ c #FE422B", " % c #BEBFBE", ".% c #A07F76", "+% c #44769E", "@% c #D55B49", "#% c #31668D", "$% c #3D749B", "%% c #366C94", "&% c #366C93", "*% c #447BA2", "=% c #3B7198", "-% c #437699", ";% c #6496BA", ">% c #37698C", ",% c #5081A5", "'% c #3C6E92", ")% c #2F6285", "!% c #434152", "~% c #95A5B4", "{% c #5E7B94", "]% c #34668E", "^% c #3E7199", "/% c #3B6E96", "(% c #2F628A", "_% c #36688F", ":% c #3A6B91", "<% c #A22816", "[% c #316285", "}% c #457798", "|% c #5F90B0", "1% c #497B9E", "2% c #3F7094", "3% c #407094", "4% c #FFA492", "5% c #E3685D", "6% c #E4E5E4", "7% c #9C9A9A", "8% c #477CA3", "9% c #407AA1", "0% c #31485E", "a% c #DED0CD", "b% c #A7B6C1", "c% c #2F4556", "d% c #324D62", "e% c #395369", "f% c #30678E", "g% c #295F87", "h% c #285E85", "i% c #3E6F91", "j% c #3B6C8F", "k% c #4E7FA1", "l% c #37678A", "m% c #356589", "n% c #5789AF", "o% c #2D3541", "p% c #292E39", "q% c #375B7A", "r% c #33668E", "s% c #366991", "t% c #36668C", "u% c #3A698E", "v% c #3D6D8E", "w% c #3E6D8E", "x% c #2D5D7D", "y% c #346387", "z% c #396A8C", "A% c #3D6D8F", "B% c #FF6543", "C% c #DFD9D8", "D% c #6C5D57", "E% c #1C1512", "F% c #385770", "G% c #6B7F90", "H% c #315573", "I% c #892313", "J% c #366990", "K% c #397096", "L% c #295A83", "M% c #3B6C95", "N% c #3A6B93", "O% c #366790", "P% c #35668F", "Q% c #30628A", "R% c #3C6D96", "S% c #32648C", "T% c #43759E", "U% c #34668F", "V% c #386992", "W% c #376891", "X% c #2D3847", "Y% c #D3D2D1", "Z% c #354C64", "`% c #527D98", " & c #44759E", ".& c #3D6F97", "+& c #2A5B84", "@& c #35658E", "#& c #C4CACE", "$& c #57616D", "%& c #202B36", "&& c #70828E", "*& c #C6321E", "=& c #8A1F0F", "-& c #F4FEFE", ";& c #FDFEFE", ">& c #3B6D95", ",& c #3C6E95", "'& c #A12917", ")& c #41729A", "!& c #497BA3", "~& c #36668F", "{& c #295981", "]& c #205078", "^& c #2D5D86", "/& c #396A92", "(& c #31618A", "_& c #42739B", ":& c #2E5F87", "<& c #376790", "[& c #34658D", "}& c #2E6088", "|& c #2A5C85", "1& c #33658D", "2& c #376991", "3& c #32648D", "4& c #326087", "5& c #615F5F", "6& c #9CA9B0", "7& c #637581", "8& c #2F6089", "9& c #5E686F", "0& c #7B5C5A", "a& c #556E7E", "b& c #306088", "c& c #FFAC8B", "d& c #FF7453", "e& c #F05230", "f& c #952211", "g& c #FEFFFE", "h& c #3F7198", "i& c #46779F", "j& c #45769E", "k& c #3E6F97", "l& c #26567E", "m& c #316088", "n& c #34648B", "o& c #2D5E86", "p& c #295982", "q& c #2A5C84", "r& c #30618A", "s& c #285A83", "t& c #366891", "u& c #42749C", "v& c #4E6C86", "w& c #65879F", "x& c #323131", "y& c #424242", "z& c #E0E0E0", "A& c #DDDDDD", "B& c #8F554A", "C& c #FF9E7E", "D& c #FF967B", "E& c #FF8462", "F& c #FF946F", "G& c #FFE0C0", "H& c #C82100", "I& c #FF5E3C", "J& c #AE3015", "K& c #FE5A3A", "L& c #FE5C3A", "M& c #FE5837", "N& c #FE5937", "O& c #FD5937", "P& c #88504A", "Q& c #3F7098", "R& c #3C6C94", "S& c #45769F", "T& c #2B5C83", "U& c #215178", "V& c #386A92", "W& c #285981", "X& c #295B82", "Y& c #275981", "Z& c #295B83", "`& c #3D6E95", " * c #3F739A", ".* c #43769E", "+* c #315473", "@* c #5C7A92", "#* c #304051", "$* c #2E2A2F", "%* c #5E676F", "&* c #395971", "** c #4578A0", "=* c #C3C3C4", "-* c #8F8E8F", ";* c #6B6769", ">* c #65160A", ",* c #B1200D", "'* c #EA7E63", ")* c #A50E01", "!* c #CE2E1E", "~* c #161B17", "{* c #D2CECE", "]* c #FFFFFF", "^* c #FFF4EB", "/* c #952E2E", "(* c #9D2A15", "_* c #943223", ":* c #4A7DA4", "<* c #3C6F96", "[* c #376990", "}* c #5588AF", "|* c #35678E", "1* c #2C5F87", "2* c #275A82", "3* c #2E6089", "4* c #2E628A", "5* c #3B6F97", "6* c #2F5372", "7* c #335776", "8* c #325676", "9* c #798998", "0* c #8C96A1", "a* c #313E4F", "b* c #251916", "c* c #D5D1D1", "d* c #261F21", "e* c #457490", "f* c #3C7098", "g* c #376A93", "h* c #32668D", "i* c #617592", "j* c #FA9381", "k* c #FFF9F7", "l* c #E8E8E8", "m* c #B51100", "n* c #C65E4B", "o* c #21130F", "p* c #DCD9D9", "q* c #C02E19", "r* c #BA2916", "s* c #BB1E0F", "t* c #040705", "u* c #E53C1B", "v* c #D52F10", "w* c #BA290E", "x* c #7D1E24", "y* c #2E6189", "z* c #5183AB", "A* c #31638A", "B* c #2B5D84", "C* c #2C5E85", "D* c #346790", "E* c #314961", "F* c #284057", "G* c #606E7C", "H* c #283747", "I* c #2F3F50", "J* c #2F3849", "K* c #251E1F", "L* c #1D120F", "M* c #291C1B", "N* c #32475A", "O* c #2D6089", "P* c #3F739B", "Q* c #42769E", "R* c #396D95", "S* c #0F0F0F", "T* c #C52A1A", "U* c #B61101", "V* c #B51000", "W* c #4C4848", "X* c #928B8A", "Y* c #A09995", "Z* c #20140F", "`* c #3C0B06", " = c #A00600", ".= c #980500", "+= c #EC3C21", "@= c #F44327", "#= c #B91A05", "$= c #703459", "%= c #31648B", "&= c #3A6C93", "*= c #407299", "== c #3D6F96", "-= c #42749B", ";= c #3C6D95", ">= c #2E6087", ",= c #2F3D4F", "'= c #2E3037", ")= c #9B9494", "!= c #241614", "~= c #231A1A", "{= c #313D4C", "]= c #2E618A", "^= c #31648C", "/= c #2C6088", "(= c #2F618B", "_= c #2F638B", ":= c #376A92", "<= c #3F729A", "[= c #24567E", "}= c #FF765C", "|= c #C62210", "1= c #BE1605", "2= c #EF391E", "3= c #790D06", "4= c #140F0E", "5= c #6F3937", "6= c #AD8481", "7= c #C9C3C1", "8= c #140804", "9= c #AF1505", "0= c #F44126", "a= c #FA462B", "b= c #D02913", "c= c #BAADBB", "d= c #32658E", "e= c #386B93", "f= c #44769D", "g= c #417399", "h= c #42739A", "i= c #38688F", "j= c #41739A", "k= c #253245", "l= c #2F5273", "m= c #32638D", "n= c #2C5D87", "o= c #3F6F99", "p= c #31618B", "q= c #2D5D87", "r= c #2A5A84", "s= c #21517B", "t= c #2A5A85", "u= c #24547E", "v= c #205179", "w= c #174871", "x= c #2C5D85", "y= c #FF5A3D", "z= c #EC4424", "A= c #FF7756", "B= c #33638B", "C= c #968AA1", "D= c #FF674E", "E= c #F03C24", "F= c #ED3920", "G= c #EF3920", "H= c #A80400", "I= c #4A0302", "J= c #570302", "K= c #A2726F", "L= c #C18481", "M= c #CBB8B5", "N= c #261611", "O= c #562118", "P= c #F04025", "Q= c #C1371E", "R= c #82818E", "S= c #386D93", "T= c #366C92", "U= c #44759C", "V= c #47769E", "W= c #43729A", "X= c #3F6A94", "Y= c #36668D", "Z= c #3D7096", "`= c #2E6187", " - c #4677A1", ".- c #2F608A", "+- c #366791", "@- c #366690", "#- c #2D5D88", "$- c #33638D", "%- c #366691", "&- c #35658F", "*- c #3A6A94", "=- c #3B6B96", "-- c #4C7DA5", ";- c #407098", ">- c #370000", ",- c #376890", "'- c #A42916", ")- c #FF5037", "!- c #FF886F", "~- c #EC381F", "{- c #CE2510", "]- c #7F0302", "^- c #750302", "/- c #800302", "(- c #921C0A", "_- c #B13B27", ":- c #D24832", "<- c #F1472C", "[- c #8F2914", "}- c #BE361B", "|- c #6F4548", "1- c #3D6B91", "2- c #3A6D93", "3- c #2D5E85", "4- c #315E87", "5- c #38658E", "6- c #426D97", "7- c #45759C", "8- c #497BA1", "9- c #3C6F95", "0- c #2E5E88", "a- c #285882", "b- c #24557F", "c- c #2C5C86", "d- c #2F5F89", "e- c #33638E", "f- c #295983", "g- c #23537E", "h- c #1E4E79", "i- c #20507B", "j- c #2E5D86", "k- c #36658E", "l- c #2D5C84", "m- c #305E87", "n- c #34628B", "o- c #38668F", "p- c #396992", "q- c #F43F26", "r- c #FF5C45", "s- c #520101", "t- c #CE1801", "u- c #B80100", "v- c #DD270E", "w- c #E1311D", "x- c #951103", "y- c #A60100", "z- c #D11E03", "A- c #E24025", "B- c #E5472C", "C- c #F2482E", "D- c #D4361D", "E- c #C24025", "F- c #AE331C", "G- c #426988", "H- c #346285", "I- c #3D6D93", "J- c #30638A", "K- c #3A6B92", "L- c #3F6D95", "M- c #336089", "N- c #3F6C95", "O- c #46729B", "P- c #3B6B95", "Q- c #34648E", "R- c #376791", "S- c #30608A", "T- c #275781", "U- c #275782", "V- c #2E5E89", "W- c #366590", "X- c #204F76", "Y- c #2A5A80", "Z- c #25547D", "`- c #2D5C85", " ; c #4D7CA4", ".; c #617767", "+; c #2E494F", "@; c #3F4A4D", "#; c #FA492F", "$; c #D14430", "%; c #F24329", "&; c #F7452A", "*; c #F23D23", "=; c #FB492E", "-; c #E75237", ";; c #CD1E03", ">; c #D12209", ",; c #C72209", "'; c #CB2F15", "); c #B9361C", "!; c #B53118", "~; c #B13F28", "{; c #6492B5", "]; c #275679", "^; c #2E6084", "/; c #396C91", "(; c #3E6F96", "_; c #45739C", ":; c #305D86", "<; c #416E97", "[; c #325F86", "}; c #4B7CA1", "|; c #447A9D", "1; c #3D6C96", "2; c #3F6E99", "3; c #36658F", "4; c #23527C", "5; c #1C4C76", "6; c #2F5F8A", "7; c #396994", "8; c #285883", "9; c #28547B", "0; c #37648B", "a; c #38648C", "b; c #335E88", "c; c #49739D", "d; c #46666D", "e; c #4B6778", "f; c #2E5359", "g; c #FC4B2F", "h; c #202C21", "i; c #121D14", "j; c #19221A", "k; c #252C27", "l; c #525254", "m; c #FF573B", "n; c #272D38", "o; c #282C39", "p; c #B5240D", "q; c #AA1800", "r; c #981901", "s; c #B12F18", "t; c #C14D36", "u; c #A02E17", "v; c #32678E", "w; c #32668C", "x; c #336389", "y; c #2E5F86", "z; c #3F6E95", "A; c #2E5A84", "B; c #2C5781", "C; c #315B85", "D; c #27557C", "E; c #34658A", "F; c #31678A", "G; c #2D6287", "H; c #22537D", "I; c #265681", "J; c #40719B", "K; c #386993", "L; c #3A6B95", "M; c #31618C", "N; c #3D6D97", "O; c #33628D", "P; c #3A668E", "Q; c #305C84", "R; c #2E5981", "S; c #28547E", "T; c #536F53", "U; c #4C574B", "V; c #EC4A2F", "W; c #2B322D", "X; c #2E3C2F", "Y; c #3A483B", "Z; c #363738", "`; c #CD5337", " > c #2A2C3A", ".> c #C93721", "+> c #282E38", "@> c #232935", "#> c #95220C", "$> c #8D0E00", "%> c #8A0F00", "&> c #A52C18", "*> c #A12D16", "=> c #8E2517", "-> c #296089", ";> c #326891", ">> c #2D5F87", ",> c #2D5D83", "'> c #29597F", ")> c #2B5A80", "!> c #2D5982", "~> c #28517B", "{> c #274F7A", "]> c #2D5A81", "^> c #34658B", "/> c #3C7295", "(> c #30658B", "_> c #356994", ":> c #3B6F9A", "<> c #32638F", "[> c #275783", "}> c #35628F", "|> c #3E6B98", "1> c #2E628B", "2> c #265A83", "3> c #2B5E86", "4> c #30628C", "5> c #295B84", "6> c #34658F", "7> c #3F719A", "8> c #4679A1", "9> c #40729B", "0> c #294462", "a> c #627F9C", "b> c #232228", "c> c #2C3649", "d> c #171817", "e> c #08080A", "f> c #000000", "g> c #161618", "h> c #262628", "i> c #272835", "j> c #A4301F", "k> c #242631", "l> c #1C1C24", "m> c #571810", "n> c #801001", "o> c #635AA6", "p> c #A22F1D", "q> c #902517", "r> c #3D6B93", "s> c #39678F", "t> c #3A6790", "u> c #2D5C83", "v> c #37668B", "w> c #3A668A", "x> c #2F5678", "y> c #1E425F", "z> c #34546E", "A> c #3A5771", "B> c #305271", "C> c #4E677C", "D> c #9EB1C0", "E> c #AFC1D1", "F> c #336590", "G> c #245581", "H> c #23537F", "I> c #376491", "J> c #37628E", "K> c #204C78", "L> c #255680", "M> c #32628C", "N> c #2D5C86", "O> c #275580", "P> c #1E4C77", "Q> c #2B5A84", "R> c #26557E", "S> c #315173", "T> c #314864", "U> c #1C1E22", "V> c #6A6B65", "W> c #0F0F12", "X> c #2B2B2E", "Y> c #151517", "Z> c #1A1A1C", "`> c #1F1F21", " , c #1A1D2A", "., c #242427", "+, c #12141B", "@, c #181A23", "#, c #101118", "$, c #423119", "%, c #7B0E00", "&, c #841200", "*, c #922817", "=, c #1C4972", "-, c #214E76", ";, c #25527A", ">, c #235079", ",, c #25567E", "', c #27587D", "), c #2B587B", "!, c #3E6588", "~, c #6B91B1", "{, c #769AB9", "], c #B8D3E4", "^, c #B8CCDF", "/, c #C8D7E3", "(, c #A0B1BF", "_, c #2F5F88", ":, c #33618B", "<, c #2E5985", "[, c #27527D", "}, c #264F7B", "|, c #23547E", "1, c #1B4973", "2, c #1A4972", "3, c #214F7A", "4, c #24527C", "5, c #2E5C86", "6, c #305E88", "7, c #587E9E", "8, c #324F70", "9, c #4D4C56", "0, c #37363E", "a, c #4B4B49", "b, c #393840", "c, c #1D1D1F", "d, c #2C2C2E", "e, c #252527", "f, c #10111A", "g, c #471B1A", "h, c #23252B", "i, c #29130E", "j, c #111317", "k, c #8F1D0B", "l, c #730A01", "m, c #2B4B72", "n, c #27537C", "o, c #27547C", "p, c #2A567F", "q, c #3F6B94", "r, c #376992", "s, c #265A85", "t, c #295C84", "u, c #45749A", "v, c #406C92", "w, c #3C698D", "x, c #47698A", "y, c #4A6884", "z, c #536E86", "A, c #7490A8", "B, c #15466C", "C, c #0C3D64", "D, c #15426A", "E, c #2A567E", "F, c #29527B", "G, c #214B74", "H, c #1C4B75", "I, c #26547E", "J, c #184670", "K, c #204D78", "L, c #204D77", "M, c #25527C", "N, c #213956", "O, c #3E3D45", "P, c #34333A", "Q, c #363733", "R, c #38373F", "S, c #33323A", "T, c #272729", "U, c #232325", "V, c #090A10", "W, c #892719", "X, c #371713", "Y, c #9F301C", "Z, c #141518", "`, c #AB4939", " ' c #902616", ".' c #27557B", "+' c #225076", "@' c #1D4B71", "#' c #26537B", "$' c #24517A", "%' c #26537C", "&' c #2C5E87", "*' c #2D628A", "=' c #32658D", "-' c #33658C", ";' c #386990", ">' c #30618C", ",' c #35648B", "'' c #36668A", ")' c #336286", "!' c #26557A", "~' c #2A587E", "{' c #27537A", "]' c #214A71", "^' c #103860", "/' c #1C4974", "(' c #214E78", "_' c #24517B", ":' c #214D78", "<' c #234F79", "[' c #234F7A", "}' c #204C77", "|' c #19446F", "1' c #233956", "2' c #30312C", "3' c #252427", "4' c #2B2A32", "5' c #1C1C1E", "6' c #0E0F15", "7' c #922B15", "8' c #0D0D0D", "9' c #9A321D", "0' c #9E3C2C", "a' c #932617", "b' c #2A5882", "c' c #245278", "d' c #28577D", "e' c #2E5C83", "f' c #2E5C84", "g' c #25527B", "h' c #2A5880", "i' c #24537C", "j' c #21517A", "k' c #26587F", "l' c #33668C", "m' c #396D9A", "n' c #326792", "o' c #275D87", "p' c #386E9A", "q' c #17456A", "r' c #0A365B", "s' c #163F66", "t' c #345C83", "u' c #1F446B", "v' c #1E446B", "w' c #1A446F", "x' c #1F4873", "y' c #26507B", "z' c #325B86", "A' c #2C5580", "B' c #29537F", "C' c #2A547F", "D' c #2F5781", "E' c #2E435A", "F' c #676E71", "G' c #606A6F", "H' c #464C50", "I' c #383F40", "J' c #303130", "K' c #2E302F", "L' c #32332F", "M' c #7E7E7D", "N' c #312E2D", "O' c #181818", "P' c #611D0A", "Q' c #262829", "R' c #B0A4A1", "S' c #7D2417", "T' c #315F89", "U' c #2E5D83", "V' c #28567C", "W' c #255379", "X' c #29577F", "Y' c #2F5D86", "Z' c #2D5A83", "`' c #2B587E", " ) c #265275", ".) c #29587B", "+) c #2B597D", "@) c #306085", "#) c #2F6186", "$) c #345D80", "%) c #2C577B", "&) c #2E5D81", "*) c #2B597E", "=) c #315D88", "-) c #17446F", ";) c #2E5B86", ">) c #2A5782", ",) c #28537D", "') c #2B5781", ")) c #26517C", "!) c #25517B", "~) c #2D5983", "{) c #325E88", "]) c #35628D", "^) c #2F577F", "/) c #2F3237", "() c #737A7A", "_) c #494B47", ":) c #333230", "<) c #35383A", "[) c #42474D", "}) c #272B31", "|) c #575A5C", "1) c #1F2020", "2) c #4C4945", "3) c #766C65", "4) c #97482A", "5) c #742C17", "6) c #722D1A", "7) c #2D5D84", "8) c #23537C", "9) c #2F5E87", "0) c #37668F", "a) c #3C6B95", "b) c #386790", "c) c #2D5B84", "d) c #3E6B95", "e) c #3A6992", "f) c #37658F", "g) c #34638C", "h) c #2B5B84", "i) c #38668E", "j) c #204E76", "k) c #225078", "l) c #19476F", "m) c #325F89", "n) c #35618C", "o) c #2C5983", "p) c #234E78", "q) c #2A557F", "r) c #2F5A85", "s) c #305C86", "t) c #335F89", "u) c #335E89", "v) c #2B5782", "w) c #315B86", "x) c #1D4873", "y) c #1F1E1E", "z) c #63717B", "A) c #3F4245", "B) c #253033", "C) c #1A1919", "D) c #2B2B29", "E) c #292822", "F) c #20201D", "G) c #6C645B", "H) c #9B928A", "I) c #76240E", "J) c #782814", "K) c #29567D", "L) c #356389", "M) c #36648A", "N) c #336188", "O) c #3B698F", "P) c #32628B", "Q) c #35648D", "R) c #3A6993", "S) c #2B5982", "T) c #26547D", "U) c #27557E", "V) c #295780", "W) c #305F88", "X) c #2C5A82", "Y) c #235179", "Z) c #305E86", "`) c #36628C", " ! c #3C6792", ".! c #517DA7", "+! c #4A75A0", "@! c #194670", "#! c #1E4A74", "$! c #29547E", "%! c #3C6691", "&! c #244D78", "*! c #19426D", "=! c #284F77", "-! c #3B628B", ";! c #293E53", ">! c #1A1818", ",! c #161616", "'! c #0F1313", ")! c #060709", "!! c #86584D", "~! c #762814", "{! c #6C2413", "]! c #4A5B7B", "^! c #5F89B3", "/! c #5A84AA", "(! c #164066", "_! c #396389", ":! c #305A7F", "~ c #3C7095", ",~ c #2E5D87", "'~ c #24537D", ")~ c #2B5E85", "!~ c #275980", "~~ c #2D6087", "{~ c #2C5B83", "]~ c #25557C", "^~ c #225279", "/~ c #24537B", "(~ c #1E4E76", "_~ c #24547C", ":~ c #23537B", "<~ c #32608B", "[~ c #31608B", "}~ c #2D5B86", "|~ c #35648F", "1~ c #2A5983", "2~ c #21507A", "3~ c #1B4A73", "4~ c #1F4E78", "5~ c #22517B", "6~ c #265680", "7~ c #3E6D97", "8~ c #3F6F98", "9~ c #25597D", "0~ c #24597D", "a~ c #396D92", "b~ c #36648E", "c~ c #275680", "d~ c #14456E", "e~ c #2C5C85", "f~ c #4A7DA7", "g~ c #3C6F99", "h~ c #2D618A", "i~ c #356892", "j~ c #31658F", "k~ c #3E7297", "l~ c #3A6E93", "m~ c #3E7197", "n~ c #32648B", "o~ c #2A5D84", "p~ c #30608E", "q~ c #2C5B8A", "r~ c #2B5A89", "s~ c #214F7E", "t~ c #295786", "u~ c #224F7E", "v~ c #16456E", "w~ c #194871", "x~ c #12426B", "y~ c #1B4B74", "z~ c #205079", "A~ c #2B6185", "B~ c #184F73", "C~ c #1A5175", "D~ c #4777A0", "E~ c #43719C", "F~ c #376691", "G~ c #386791", "H~ c #386892", "I~ c #285982", "J~ c #4676A0", "K~ c #396893", "L~ c #4877A1", "M~ c #386891", "N~ c #396891", "O~ c #40729A", "P~ c #33628C", "Q~ c #2F5B86", "R~ c #3B6691", "S~ c #41719A", "T~ c #295882", "U~ c #2A5A83", "V~ c #25547E", "W~ c #3A6892", "X~ c #386691", "Y~ c #4F7EA8", "Z~ c #45749E", "`~ c #32618B", " { c #2B5B85", ".{ c #3C6C96", "+{ c #3B6B94", "@{ c #44749D", "#{ c #4E7DA7", "${ c #4B7BA4", "%{ c #46759F", "&{ c #3E6E97", "*{ c #4878A1", "={ c #2E6289", "-{ c #23567E", ";{ c #46769F", ">{ c #5685AE", ",{ c #5382AC", "'{ c #416E99", "){ c #4C7CA6", "!{ c #4978A2", "~{ c #42729B", "{{ c #295781", "]{ c #14426C", "^{ c #24527D", "/{ c #43729C", "({ c #4D7BA5", "_{ c #42709A", ":{ c #20507A", "<{ c #1F4F79", "[{ c #376690", "}{ c #285881", "|{ c #34658E", "1{ c #3C6B94", "2{ c #2E5E87", "3{ c #3F6E98", "4{ c #3A6A93", "5{ c #316089", "6{ c #4778A2", "7{ c #42729C", "8{ c #1F4E79", "9{ c #2B5A85", "0{ c #305E89", "a{ c #3F6D97", "b{ c #4E7DA6", "c{ c #4A79A3", "d{ c #4B7AA4", "e{ c #4F7EA7", "f{ c #42719B", "g{ c #3E7099", "h{ c #3D6F98", "i{ c #4977A1", "j{ c #3D6C95", "k{ c #5180A9", "l{ c #4D7CA5", "m{ c #43729B", "n{ c #35628B", "o{ c #36648D", "p{ c #396790", "q{ c #3E6C95", "r{ c #416F99", "s{ c #24537E", "t{ c #26557F", "u{ c #275882", "v{ c #30618B", "w{ c #31628C", "x{ c #23527D", "y{ c #295883", "z{ c #40709A", "A{ c #4C7BA5", "B{ c #406E98", "C{ c #3D6893", "D{ c #3E6D96", "E{ c #3B6C96", "F{ c #356992", "G{ c #295E85", "H{ c #33618A", "I{ c #44739C", "J{ c #3D6B95", "K{ c #3B6993", "L{ c #396993", "M{ c #44739D", "N{ c #4978A1", ". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } } | 1 2 3 4 5 3 5 6 7 8 9 0 a b c d e f g ", "h i j k h l m n o p q p r s t u v w x y z A B C D E F G H I I J K L M N L O P Q R S T U V W X Y ", "m h k Z ` k . ...+.@.$ #.$.%.&.&.o *.=.-.;.>.,.'.).,.!.~.{.~.].^./.(._.:.<.[.}., |.1.2.3.4.5.6.", "7.8.9.0.a.b.c.d.e.f. .g.h.i.j.k.l.m.n.o.p.q.r.s.n.t.u.v.w.x.x.y.z.z.A.B.C.D.E.F.G.H.I.J.K.L.M.N.", "O.P.Q.R.S.T.U.V.W.X.Y.Z.U.n `. +.+++$.@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+)+^+/+(+_+:+<+[+}+|+1+2+", "3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+0+k+Z.l+m+n+o+p+q+r+o+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+K+", "L+M+N+O+P+Q+W.R+S+T+U+V+W+X+X.Y+V+Z+`+ + @.@m++@@@v+#@#@$@@@V+%@v+&@*@#@=@-@;@>@1+,@'@)@!@^+~@{@", "]@^@/@(@_@:@<@[@}@|@c+V+1@R+j+2@3@4@u+5@6@7@c+8@V+9@0@@.n+a@b@V..+c@d@e@=@-@f@g@h@i@j@k@l@m@n@o@", "p@q@r@s@t@u@v@w@(@x@y@/@X.z@A@B@C@B@^@V.D@&@V.E@F@5@G@H@I@c@9@J@J@K@D@L@=@-@&+M@7@N@O@P@-+Q@R@S@", "T@U@V@W@X@Y@w@y@Z@`@W. #z@.#y@+#@#P@L@@#b.##$#E@%#&#*#=#H@-#E@$#G@&#;###>#,#'#a+)#!#E@P@&@e.~#1@", "{#]#^#/#(#_#:#<#[#}#[#|#1#v@2#3#}#W.|#4#B@5@C@e.a+++5#6#=#=# @9@c@/@*##8#P@9#0#a#b#c#d#P@P@R+", "e#6+f#g#h#i#:#O+}#j#T+k#l#m#n#o#:#p#q#r#s#t#u#s+v#w#x#y#z#A#B#C#D#j#C#y#E#F#G#H#I#J#K#L#1@M#N#O#", "P#e#Q#R#S#T#U#V#W#X#Y#s@Z#`# $b#.$+$@$^##$$$%$&$*$=$-$;$>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$1$2$3$", "6+4$5$6$D#7$3#8$9$0$X#a$!$n+f+;$~$b$c$a@d$e$f$g$h$i$o+j$k$l$m$Y+n$o$p$q$r$s$J#t$<$u$s#v$w$x$y$z$", "A$B$6+7+_@C$<#Z@x@4#V.D$E$F$G$H$I$G$J$K$L$M$N$O$P$Q$t$R$S$T$U$V$W$X$Y$Z$`$ %.%Y++%V+@%>$#%~#2$8@", "_@$%<#%%&%D@*%(@=%A@z@y@-%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%|%A.1%2%3%4%5%6%7%8%9%0%a%b%c%d%e%S+", "f%g%h%w$0+y@y@@#D@M#c@#@i%i%j%k%l%m%n%o%p%q%L$r%s%t%u%<%v%w%x%y%z%A%l%B%C%D%E%F%G%H%I%J%M#K%a+a+", "L%M%%$N%v$O%<$P%s#Q%R%S%a@+%T%]%U%V%c$W%X%Y%Z%`% &.&e$<%+&@&s##&$&%&&&*&=&-&;&>&,&z$'&)&s#m+s+!&", "J#~&{&]&^&/&(&_&@&:&<&[&}&|&1&2&]%2&3&}&z$4&5&6&7&8&9&0&a&b&O%t#t#c&d&e&f&g&c$h&i&j&<%k&k&$@)&[&", "l&{&m&n&o&^&p&s#~&[&:&[&]#q&r&2&s&t&u&m+3$v&w&x&y&z&A&B&C&D&E&F&G&H&I&J&K&L&M&N&O&O&P&m+Q&s#R&S&", "}&T&T&U&+&V&t$W&X&Y&Z&`& *.*+*@*#*$*%*&*.&b+**=*-*;*>*,*'*)*!*~*{*]*^*/*(*_*:*:*1&<*[*X+}*k$/&|*", "@$1*2*3*4*5*6*7*8*9*0*a*b*c*d*e*f*g*h*5*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*_%3@>$X&3@z*A*B*C*|*i+", "D*E*F*G*H*I*J*K*L*M*N*u@X#O*s@+$7$P*Q*R*S*S*T*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=&=*=[*==-=3$,&;=}&>=}&", ",='=)=!=~={=+*]=O*^=/=(=_=/%k#:=4*<=j#5*[=}=|=1=2=3=4=5=6=7=8=9=0=a=b=c=d=e=J$2&f=g=k&h=i===m+j=", "k=l=m=n=o=o=p=q=r=s=t=u=v=w=x=;=y=z=A=B=C=D=E=F=G=H=I=J=K=L=M=N=O=P=Q=R=<*S=T=S===U=V=W=X=Y=Z=`=", " -.-+-u=@-#-t=$-%-&-*-=-t#_&--;->-,-'-'-)-!-~-2=~-{-]-^-/-(-_-:-<-[-}-|-1-2-;$d+>$3-4-5-6-7-8-9-", "0-a-0-b-c-d-$-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-v-w-x-y-z-A-B-C-D-E-F-G-H-I-[*J-K-L-M-N-O-:%==_%", "P-Q-R-&-Q-S-T-U-V-o=W-q=4&X-Y-Z-`- ;.;+;@;#;$;%;&;*;=;-;;;>;,;';);!;~;{;];^;/;F$(;_;:;<;[;};|;~#", "1;2;3;4;s=5;6;p=P-7;0-8;9;0;a;b;c;d;e;f;g;h;i;j;k;l;m;n;o;p;q;r;s;t;u; #v;w;x;y;z;A;B;C;D;E;F;G;", "0-H;I;Q-J;K;L;M;P-N;O;*-P;Q;R;S;T;U;U;V;W;X;Y;Z;`; >.>+>@>#>$>%>&>*>=>->;>>>,>'>)>!>~>{>]>^>/>(>", "_>:><>[>}>|>1>2>3>4>5>6>7>8>9>0>a>b>c>d>e>f>g>h> >i>j>k>l>m>n>o>p>q>r>s>t>u>v>w>x>y>z>A>B>C>D>E>", "F>G>H>I>J>K>L>$-M>N>O>P>Q>p&R>S>T>U>V>W>X>Y>Z>`> ,.,+,@,#,$,%,&,*,=,-,;,>,,,:&',),!,~,{,],^,/,(,", "_,u$:,<,[,},|,1,2,3,4,5,m-6,7,8,9,0,a,b,c,c,d,e,f,g,h,#,i,j,k,l,m,n,o,p,q,r,s,t,r&u,v,w,x,y,z,A,", "B,C,D,E,F,G,H,I,I,I,J,K,L,M,N,O,O,P,Q,0,R,S,T,U,V,W,X,Y,Z,`, '.'+'@'#'$'%'&'g%*'='1&-';'>',''')'", "!'~'{']']'^'/'('_':'<'['}'|'1'S,S,S,2'3'4'S,d,5'6'7'8'9'0'a'b'c'd'e'f'g'h'i'j'k'-=-=,&l'm'n'o'p'", "q'r's't'u'v'w'x'y'z'A'B'C'D'E'F'G'H'I'J'K'L'M'N'O'P'Q'R'S'T'k-U'V'W'X'Y'Z'`' ).)+)!'@)#)$)%)&)*)", "=)-);)>),)A;')))!)!)~){)])^)/)()_):)<)[)})|)1)2)3)4)5)6)b&7)b&8)9)@&0)a)b)c)d)e)f)g)0)h)i)j)k)l)", "m)n)o)B;[,p)q)r)s)t)u)v)w)x)y)z)A)B)C)D)E)F)G)H)I)J)K)L)M)N)O)<&P)N>Q)0)R)S)T)U)V)R>W)$$X)Y)Y)Z)", "`) !.!+!Y'@!#!!)$!%!&!*!=!-!;!>!,!'!)!N'!!~!{!]!^!/!(!_!:!5!p&6!Q)m-1!U)c)", "7!8!~)9!c)U)7!!)0!a!p,b!c!d!e!f!g!h!i!j!k!l!&!{>m!n!o!p!q!r!s!t!b'3!u!v!T'w!x!$$a)%$y!4!z!A!B!v$", "C!D!E!b'F!c)G!2!H!I!t!J!K!L!M!N!O!P!Q!R!S!T!U!g'V!W!X!Y!Z!`! ~.~+~|!@~#~$~N>%~|!&~*~=~~&-~;~>~b+", ",~'~4;#~6,I!2!I!3;3;#$|!)~!~~~#~(&Q>{~]~^~/~(~_~:~O><~[~}~<~|~&~1~2~H,3~4~5~6~6~&~7~8~=~9~0~a~P$", "k-4!#~Q>b~2~R>c~c~j'd~e~(#f~g~h~i~j~!$k~l~m~s%n~o~p~q~r~s~t~u~v~w~x~4~Q>w!h)w!^&y~z~$$1~A~B~C~1*", "8)_,o=D~E~F~#~G~H~@-c-I~q=@-Q-N;J~&-K~L~M~e)0)a)N~G@Z+O~P~Q~R~P)w!_,&~S~$~P~%~j-T~U~V~h)~&P~,~`-", "5~4;4!W~X~Y~Z~b~`~~&4;6! {R-c-.{o=S-+{@{#{${%{&{*{={-{;{>{,{'{){!{y!a-+{M~M~8~Q)N;&~1;1;~{Z~Z~&$", "6,{{H!3!J,]{2~^{1~/{({_{.~*-&-a-:{:{<{[{P)c~y~}{y!N$|{%~8~.~1{~{=~~{~{T~U~2{%$3{p-2~^&N>4{5{(&G~", "6{7{S-M>G~`~5;8{9{|~P~0{[{[{N~Z~@~3;a{b{c{d{1;a)[{&~e{Y~f{g{h{7~i{j{k{l{m{n{o{p{q{r{&~s{t{ {8)z~", "u{v{w{b-x{y{*-q=Q-*-z{K~5{w!1!4;9)g)G~N~!{A{B{d{Z~C{D{Q)E{F{G{&~L~@&N>9)0)H{I{J{K{g)1;L{M{N{7~j{"}; searchandrescue_1.7.0/HACKING0000664000175000001440000002353312046776371015004 0ustar jesseusers S E A R C H A N D R E S C U E V E R S I O N 0.8.4 HACKING GUIDE For contributors, builders, or those interested in the finer details behind the scenes; this document details the source files with their related purpose in this program along with outlines of non-intuitive areas of the code. Note: Version represented in this document may be out of date, verify version above with actual version of accompanying source. -------- CONTENTS * Submitting Changes * Source Layout ------------------ SUBMITTING CHANGES If you have a patch or a change you'd like to submit, please send an e-mail to jessefrgsmith@yahoo.ca. The e-mail shold include * Your name, so you can get credit * A brief descrption of the change * An attachment with the patch We prefer small patches with lots of documentation. We respond to all received patches, so if you didn't hear back from us within a week, the e-mail got lost in a spam filter. Please resubmit or contact us via the forum at http://searchandrescue.forumwise.com ------------- SOURCE LAYOUT Note, $TOPLEVEL represents this source's toplevel directory. Most (not all) .c and .cpp files will have an accompany .h file with the same name. In $TOPLEVEL/include: These file are global include files for most of the general globally shared functions. In $TOPLEVEL/sar: This is the source directory for the program. Makefile.* Makefiles for compiling and installing under UNIXes. Makefile.srclist List of header files and sources for other Makefiles. cmd.c SAR Command line front end, passes inputs to other functions in cmd*.c sources. See cmd.h for a list of command and function pointer referances. cmd*.c SAR Command line handler functions. config.h SAR Globally configurable constants. cp.c Control panel cpins*.c Control panel instruments explosion.c Explosion (and splash) object creation. fire.c Fire object creation. gctl.c Game controller (keyboard, joystick, etc) input wrapper, takes input from device specific functions and updates the game controller (gctl) values which other functions rely on for controller values. gw.h GUI wrapper header. gww.cpp MSW GUI wrapper functions. gwx.c X11 GUI wrapper functions. gwx_dialog.c X11 GUI dialog wrapper functions (since Xlib does not have a built in dialog system). horizon.c Generates a 1d horizon texture. human.c Human object preset list, manages a preset list of values for creation of standard human objects. humanio.c Human object preset list file IO. image.c IO and drawing of images, using the GUI wrapper functions to draw them. main.c Program main function and other core operations functions (including timming, signal handler, GUI wrapper callbacks, etc). See sar.h for header info. matrixmath.c Matrix translation and rotation utilities, mostly for 3 * 1 or 3 * 3 matrix operations. menu.c SAR menu object (widgets) core. menumap.c SAR map menu object (widget) handler. messages.c Handles and draws messages printed on screen in game. mission.c Mission handling core. missionio.c SAR .mis mission file IO. musiclistio.c SAR music file referance list IO. obj.h SAR object definations. objio.c SAR .3d object file IO, also has other object load from file utils and routines. objiocb.c SAR scene and object file loading progress callback. objiopremodeled.c Creates SAR premodeled objects. objsound.c SAR object sound source management. objutils.c SAR scene and object utility functions, including deleting, checking, list io, etc. optionio.c SAR options/preferances file IO. sar.h SAR core header file. sarcamp.c Functions for dealing with random Campaigns. sarcamp.h Headers and definitions for working with Campaigns. sardraw.c SAR in game drawing routines, uses OpenGL and a bit of the GUI wrapper code. sardrawhelipad.c SAR helipad drawing (also for drawing map icon of helipad). sardrawhuman.c SAR human drawing. sardrawpremodeled.c Supplmentary functions for sardraw.c to draw premodeled SAR objects. sardrawrunway.c SAR runway drawing (also for drawing map icon of runway). sarfio.c SAR file format (scenery, mission, and log files) IO. This module allocates and deallocates parameters, see sarfioopen.c for actual loading of parameters from file and sarfiosave.c for actual writing of parameters to file. sarfioopen.c SAR file format loading, loads parameters from file. sarfiosave.c SAR file format writing, writes parameters to file. sarfps.c Frames per second tallying functions. sarinstall.c Creates/coppies global program configuration and data files/dirs to local user's directory. sarkey.c In game keyboard key handling, called from functions in main.c. If key input is not handled, it will be passed to the gctl.c functions. sarmenubuild.c Creates the menu and their menu objects (widgets), then sets up the initial data and callbacks. sarmenucb.c SAR menu callback handlers. sarmenuoptions.c SAR supplmentary callbacks for the options menu, also includes options fetch and apply to menu objects (widgets) functions. See also optionio.c and sarmenucb.c. sarsimbegin.c SAR simulation begin procedure for free flight and missions. This is used to switch from menus to simulation and load a scenery or mission. sarsimend.c SAR simulation end procedure and tabulation for missions. This is used to end a simulation (with or without a mission) and switch back to the menus. sarsound.c SAR sound object management, handles things like sound object creations, background music updating, and engine sound object adjustments. See also scenesound.c and sound.c. sarsplash.c Splash screen procedure, called after graphics wrapper is just initialized by SARInit(). sartime.c SAR time utility functions. sarutils.c SAR primary utility functions that handle SAR global and core level things. sarreality.h SAR simulation, reality, and timming constants. sceneio.c SAR .scn scene file loading, subsequently calls load object routines in objio.c. The scene deallocation function is also in here. scenesound.c Updates SAR scene sound resources, should be used after all objects are loaded when sound needs to be realized or during simulation when the sound level changes. sfm*.c SAR Flight Dynamics Model (SFM) library, called by the sim*.c functions. Note that this is really an intigrated library, it may be made into a shared library (so) later on. sfm.c SFM realm init, shutdown, and management. sfmmath.c SFM math utilities, includes conversions and angle calculation functions. sfmmodel.c SFM flight dynamics model IO. sfmsimforce.c SFM flight dynamics model engine, simulates forces acted on the fdm. sim*.c SAR simulation functions, calls and manages sfm*.c functions. simcb.c SAR simulation callbacks for the SFM. simcontact.c SAR simulation object to object contact/collision checking and handling. simmanage.c SAR simulation core functions, primary calling source to the SFM functions. simop.c SAR simulation operations and procedures, mostly procedure functions called by simmanage.c. simsurface.c SAR simulation surface checking, checks position against landable/walkable ground. simutils.c SAR simulation calculation and simple modification utility functions. smoke.c SAR smoke object creation. Simple convience function to create a smoke object. See also objutils.c sound.c Y2 sound wrapper, handles playing and management of Y sound play objects. This is the lowest level of code which communicates with the sound output library and the rest of the program. See also sarsound.c and scenesound.c stategl.c Used with gw*.c* sources, manages the state of OpenGL so calling functions can enable/disable multiple times without wasting OpenGL bandwidth. text3d.c Generates gl output or a gl list of a 3d text using the x3d.c module. textinput.c In game text input prompt handling, handles drawing and key events forwarded to the text prompt. Calling functions need check if prompt is mapped before forwarding key event to it. texturelistio.c Standard textures list IO, loads a list of referances to standard textures to be loaded for each scene. v3d*.c Vertex 3D (V3D) visual models and textures IO. Note that this is really an intigrated library, it may be made into a shared library (so) later on. v3dfio.c V3D visual model file IO. v3dhf.c V3D heightfield image file IO. v3dmodel.c V3D visual model IO. v3dmh.c V3D visual model header items IO, header items used in recording the header block items in each V3D visual model. v3dmp.c V3D visual model primitives IO, primitives used on each V3D visual model. v3dtex.c V3D texture (image) file IO. weather.c Weather preset values initializing, management, shutdown, and utilities. Include utility to update a given scene structure with a selected preset weather data entry. weatherio.c Weather file IO. x3d.c X3D model file format, for loading of compile time gl models to gl output or gl list. In $TOPLEVEL/sar/fonts: Compile time bitmap fonts (used by the gw module). In $TOPLEVEL/sar/gwdata: Compile time data files for the graphics wrapper (gw module). In $TOPLEVEL/sar/gwdemos: Demo programs for the graphics wrapper (extra). In $TOPLEVEL/sar/runway: Compile time X3D models for the SAR runway. In $TOPLEVEL/sar/text3d: Compile time X3D models for the text3d module. In $TOPLEVEL/sar/utils: Utility programs used to generate the compile time fonts and such (extra). ----------------- SEARCH AND RESCUE searchandrescue_1.7.0/Makefile0000664000175000001440000000026612046776371015453 0ustar jesseusersALL_SRC_DIRS=sar all install clean: @for subdir in $(ALL_SRC_DIRS); do \ [ ! -f $$subdir/Makefile ] || make -s -C $$subdir -f Makefile $@; \ done data: ./installsardata searchandrescue_1.7.0/sar/0000755000175000001440000000000013452215465014564 5ustar jesseuserssearchandrescue_1.7.0/sar/v3dgl.c0000664000175000001440000010713013452207027015746 0ustar jesseusers#include #include #include #include #include #include #include "../include/os.h" #ifdef __MSW__ # include #endif #include #include #include "../include/disk.h" #include "../include/string.h" #include "v3dgl.h" #include "v3dhf.h" #include "v3dtex.h" /* GL interpritation structure IO. */ v3d_glinterprite_struct *V3DGLInterpriteNew(void); void V3DGLInterpriteDelete(v3d_glinterprite_struct *glinterp); /* GL resource IO and management. */ v3d_glresource_struct *V3DGLResourceNew(void); v3d_glresource_struct *V3DGLResourceNewFromModelData( const v3d_glinterprite_struct *glinterp, void **mh_item, int total_mh_items, v3d_model_struct **model, int total_models ); int V3DGLResourceSetInterpritation( v3d_glresource_struct *glres, const v3d_glinterprite_struct *glinterp ); v3d_glinterprite_struct *V3DGLResourceGetInterpritation( v3d_glresource_struct *glres ); void V3DGLResourceDelete(v3d_glresource_struct *glres); /* V3D model to GL interpritation processing. */ static void V3DGLSetNormal( v3d_glinterprite_struct *glinterp, mp_vertex_struct *n ); static void V3DGLSetTexCoord( v3d_glinterprite_struct *glinterp, mp_vertex_struct *v, mp_vertex_struct *tc, int texture_binded, void *p_texture_orient ); static void V3DGLSetVertex( v3d_glinterprite_struct *glinterp, mp_vertex_struct *v ); static void V3DGLProcessModelOtherData( v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ); static void V3DGLProcessModelStandard( v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ); void V3DGLProcessModelExtra( v3d_glresource_struct *glres, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ); void V3DGLProcessModel( v3d_glresource_struct *glres, v3d_model_struct *m ); #ifndef PI # define PI 3.14159265359 #endif #define SQRT(x) (((x) > 0.0f) ? sqrt(x) : 0.0f) #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define RADTODEG(r) ((r) * 180 / PI) /* * Allocates a new gl interpritation structure with all values * reset. */ v3d_glinterprite_struct *V3DGLInterpriteNew(void) { v3d_glinterprite_struct *glinterp = (v3d_glinterprite_struct *)calloc( 1, sizeof(v3d_glinterprite_struct) ); return(glinterp); } /* * Deallocates the given gl interpritation structure and all * its allocated resources. */ void V3DGLInterpriteDelete(v3d_glinterprite_struct *glinterp) { unsigned int flags; if(glinterp == NULL) return; flags = glinterp->flags; /* Deallocate any dynamically allocated members. */ /* Heightfield base directory. */ if(flags & V3D_GLFLAG_HEIGHTFIELD_BASE_DIR) { free(glinterp->heightfield_base_dir); glinterp->heightfield_base_dir = NULL; } /* Texture base directory. */ if(flags & V3D_GLFLAG_TEXTURE_BASE_DIR) { free(glinterp->texture_base_dir); glinterp->texture_base_dir = NULL; } /* Deallocate GL interpritation structure itself. */ free(glinterp); } /* * Allocates a new gl resources structure with all values * reset. */ v3d_glresource_struct *V3DGLResourceNew(void) { v3d_glresource_struct *glres = (v3d_glresource_struct *)calloc( 1, sizeof(v3d_glresource_struct) ); if(glres != NULL) { /* Allocate dynamically allocated members of the gl resource * structure. */ /* gl interpritation structure. */ glres->glinterprite = V3DGLInterpriteNew(); } return(glres); } /* * Allocates a new gl resources structure with the values * initialized with respect to the given V3D model data. * * If the given v3d_glinterprite_struct *glinterp is not NULL then * its values will be coppied to the new gl resources structure * and overrides any values defined in the model header items. * * The correct gl context must be binded before calling this * function. */ v3d_glresource_struct *V3DGLResourceNewFromModelData( const v3d_glinterprite_struct *glinterp, void **mh_item, int total_mh_items, v3d_model_struct **model, int total_models ) { int i, n; unsigned int interp_flags; int tex_dest_fmt = V3D_TEX_FORMAT_RGBA; void *h; mh_texture_load_struct *h_texture_load; const char *texture_base_dir; v3d_glresource_struct *glres = V3DGLResourceNew(); if(glres == NULL) return(NULL); /* Get interpritation flags that define what values that are set * in the gl interpritation structure. */ interp_flags = (glinterp != NULL) ? glinterp->flags : 0; /* Get texture base directory. */ texture_base_dir = (const char *)V3DMHTextureBaseDirectoryGet( mh_item, total_mh_items ); /* Interpritation structure overrides? */ if(interp_flags & V3D_GLFLAG_TEXTURE_BASE_DIR) texture_base_dir = glinterp->texture_base_dir; /* Load textures by iterating through model header items. */ for(i = 0; i < total_mh_items; i++) { h = mh_item[i]; if(h == NULL) continue; /* This header item specify a texture load? */ if((*(int *)h) == V3DMH_TYPE_TEXTURE_LOAD) { v3d_texture_ref_struct *t; char tmp_path[PATH_MAX + NAME_MAX]; h_texture_load = (mh_texture_load_struct *)h; if(h_texture_load->path == NULL) continue; if(ISPATHABSOLUTE(h_texture_load->path)) { strncpy(tmp_path, h_texture_load->path, PATH_MAX + NAME_MAX); } else if(texture_base_dir != NULL) { const char *cstrptr = (const char *)PrefixPaths( texture_base_dir, h_texture_load->path ); if(cstrptr == NULL) continue; strncpy(tmp_path, cstrptr, PATH_MAX + NAME_MAX); } else { strncpy(tmp_path, h_texture_load->path, PATH_MAX + NAME_MAX); } tmp_path[PATH_MAX + NAME_MAX - 1] = '\0'; t = V3DTextureLoadFromFile2D( tmp_path, h_texture_load->name, tex_dest_fmt, NULL, NULL ); if(t != NULL) { /* Texture loaded successfully. */ /* Set texture priority. */ V3DTexturePriority(t, h_texture_load->priority); /* Allocate more texture pointers on GL resource. */ n = glres->total_textures; glres->total_textures = n + 1; glres->texture = (v3d_texture_ref_struct **)realloc( glres->texture, glres->total_textures * sizeof(v3d_texture_ref_struct *) ); if(glres->texture == NULL) { glres->total_textures = 0; V3DTextureDestroy(t); break; } glres->texture[n] = t; t = NULL; } } } /* Override any GL interpritation values? */ if(glinterp != NULL) V3DGLResourceSetInterpritation(glres, glinterp); return(glres); } /* * Sets the given gl resources structure's gl interpritation * legend to the given glinterp. * * Returns non-zero on error. */ int V3DGLResourceSetInterpritation( v3d_glresource_struct *glres, const v3d_glinterprite_struct *glinterp ) { unsigned int flags; v3d_glinterprite_struct *t_glinterp; if((glres == NULL) || (glinterp == NULL)) return(-1); flags = glinterp->flags; /* Get target gl interpritation structure from the given gl * resource structure. */ t_glinterp = glres->glinterprite; if(t_glinterp == NULL) return(-1); if(flags & V3D_GLFLAG_COORDINATE_AXIS) t_glinterp->coordinate_axis = glinterp->coordinate_axis; if(flags & V3D_GLFLAG_TEXTURE_KEEP) t_glinterp->texture_keep = glinterp->texture_keep; if(flags & V3D_GLFLAG_ALLOW_TRANSLATIONS) t_glinterp->allow_translations = glinterp->allow_translations; if(flags & V3D_GLFLAG_ALLOW_ROTATIONS) t_glinterp->allow_rotations = glinterp->allow_rotations; if(flags & V3D_GLFLAG_FLIP_WINDING) t_glinterp->flip_winding = glinterp->flip_winding; if(flags & V3D_GLFLAG_PASS_NORMALS) t_glinterp->pass_normals = glinterp->pass_normals; if(flags & V3D_GLFLAG_UNITLIZE_NORMALS) t_glinterp->unitlize_normals = glinterp->unitlize_normals; if(flags & V3D_GLFLAG_PASS_TEXCOORDS) t_glinterp->pass_texcoords = glinterp->pass_texcoords; if(flags & V3D_GLFLAG_TEXTURE_NAME_CASE_SENSITIVE) t_glinterp->texture_name_case_sensitive = glinterp->texture_name_case_sensitive; if(flags & V3D_GLFLAG_MATERIAL_PROPERTIES) t_glinterp->material_properties = glinterp->material_properties; if(flags & V3D_GLFLAG_FACES) t_glinterp->faces = glinterp->faces; if(flags & V3D_GLFLAG_ENABLE_BLENDING) t_glinterp->enable_blending = glinterp->enable_blending; if(flags & V3D_GLFLAG_SET_BLEND_FUNC) t_glinterp->set_blend_func = glinterp->set_blend_func; if(flags & V3D_GLFLAG_HEIGHTFIELD_BASE_DIR) { const char *src_str = glinterp->heightfield_base_dir; free(t_glinterp->heightfield_base_dir); t_glinterp->heightfield_base_dir = STRDUP(src_str); } if(flags & V3D_GLFLAG_TEXTURE_BASE_DIR) { const char *src_str = glinterp->texture_base_dir; free(t_glinterp->texture_base_dir); t_glinterp->texture_base_dir = STRDUP(src_str); } /* Update flags on the target glinterp. */ t_glinterp->flags |= flags; return(0); } /* * Returns the gl interpritation structure from the given gl * resources structure. * * The returned value should not be modified or deallocated. * * Can return NULL on error. */ v3d_glinterprite_struct *V3DGLResourceGetInterpritation( v3d_glresource_struct *glres ) { return((glres != NULL) ? glres->glinterprite : NULL); } /* * Deallocates all resources on the given gl resources * structure. * * The correct gl context must be binded before calling this * function. */ void V3DGLResourceDelete(v3d_glresource_struct *glres) { int i; if(glres == NULL) return; /* Unload and deallocate all textures. */ for(i = 0; i < glres->total_textures; i++) V3DTextureDestroy(glres->texture[i]); free(glres->texture); glres->texture = NULL; glres->total_textures = 0; /* Deallocate gl interpritation structure. */ V3DGLInterpriteDelete(glres->glinterprite); glres->glinterprite = NULL; /* Deallocate structure itself. */ free(glres); } /* * Sets the given normal with respect to the glinterp values. */ static void V3DGLSetNormal( v3d_glinterprite_struct *glinterp, mp_vertex_struct *n ) { int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC; int pass_normals = V3D_GLPASS_NORMALS_AS_NEEDED; int unitlize_normals = TRUE; mp_vertex_struct tn; if(n == NULL) return; if(glinterp != NULL) { if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS) coordinate_axis = glinterp->coordinate_axis; if(glinterp->flags & V3D_GLFLAG_PASS_NORMALS) pass_normals = glinterp->pass_normals; if(glinterp->flags & V3D_GLFLAG_UNITLIZE_NORMALS) unitlize_normals = glinterp->unitlize_normals; } /* Never pass normals? */ if(pass_normals == V3D_GLPASS_NORMALS_NEVER) return; /* Check if normal vector is empty. */ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) { /* It's empty, check if we should pass empty normal * vectors. */ if(pass_normals != V3D_GLPASS_NORMALS_ALWAYS) return; } /* Copy normal to our local target normal for later * manipulation. */ tn.x = n->x; tn.y = n->y; tn.z = n->z; if(unitlize_normals && ((tn.x != 0.0) || (tn.y != 0.0) || (tn.z != 0.0)) ) { double mag = SQRT( (tn.x * tn.x) + (tn.y * tn.y) + (tn.z * tn.z) ); if(mag > 0.0) { tn.x = tn.x / mag; tn.y = tn.y / mag; tn.z = tn.z / mag; } } /* Set by coordinate axis type. */ switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glNormal3d(tn.x, tn.y, tn.z); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glNormal3d(tn.x, tn.z, -tn.y); break; } } /* * Sets the given texcoord with respect to the glinterp values. */ static void V3DGLSetTexCoord( v3d_glinterprite_struct *glinterp, mp_vertex_struct *v, mp_vertex_struct *tc, int texture_binded, void *p_texture_orient ) { int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC; int pass_texcoords = V3D_GLPASS_TEXCOORDS_AS_NEEDED; if(tc == NULL) return; if(glinterp != NULL) { if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS) coordinate_axis = glinterp->coordinate_axis; if(glinterp->flags & V3D_GLFLAG_PASS_TEXCOORDS) pass_texcoords = glinterp->pass_texcoords; } /* Never pass texcoords? */ if(pass_texcoords == V3D_GLPASS_TEXCOORDS_NEVER) return; /* No texture is binded? */ if(!texture_binded) { /* No texture binded, check if we should pass texcoord. */ if(pass_texcoords != V3D_GLPASS_TEXCOORDS_ALWAYS) return; } /* Orienting texcoord by plane? */ if((p_texture_orient != NULL) && (v != NULL)) { mp_texture_orient_xy_struct *orient_xy; mp_texture_orient_yz_struct *orient_yz; mp_texture_orient_xz_struct *orient_xz; double s, t; switch(V3DMPGetType(p_texture_orient)) { case V3DMP_TYPE_TEXTURE_ORIENT_XY: orient_xy = (mp_texture_orient_xy_struct *)p_texture_orient; if(orient_xy->dx > 0.0) s = (v->x - orient_xy->x) / orient_xy->dx; else s = 0.0; if(orient_xy->dy > 0.0) t = (v->y - orient_xy->y) / orient_xy->dy; else t = 0.0; /* V3D texture coordinate origin is upper left while GL * is lower left, remember to flip the t. */ glTexCoord2d(s, 1.0 - t); break; case V3DMP_TYPE_TEXTURE_ORIENT_YZ: orient_yz = (mp_texture_orient_yz_struct *)p_texture_orient; if(orient_yz->dy > 0.0) s = -(v->y - orient_yz->y) / orient_yz->dy; else s = 0.0; if(orient_yz->dz > 0.0) t = (v->z - orient_yz->z) / orient_yz->dz; else t = 0.0; /* V3D texture coordinate origin is upper left while GL * is lower left, remember to flip the t. */ glTexCoord2d(s, 1.0 - t); break; case V3DMP_TYPE_TEXTURE_ORIENT_XZ: orient_xz = (mp_texture_orient_xz_struct *)p_texture_orient; if(orient_xz->dx > 0.0) s = (v->x - orient_xz->x) / orient_xz->dx; else s = 0.0; if(orient_xz->dz > 0.0) t = (v->z - orient_xz->z) / orient_xz->dz; else t = 0.0; /* V3D texture coordinate origin is upper left while GL * is lower left, remember to flip the t. */ glTexCoord2d(s, 1.0 - t); break; } } /* Set texcoord explicitly by the given tc. */ else { double s = tc->x; double t = tc->y; /* V3D texture coordinate origin is upper left while GL * is lower left, remember to flip the t. */ switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glTexCoord2d(s, t); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glTexCoord2d(s, 1.0 - t); break; } } } /* * Sets the given vertex with respect to the glinterp values. */ static void V3DGLSetVertex( v3d_glinterprite_struct *glinterp, mp_vertex_struct *v ) { int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC; if(v == NULL) return; if(glinterp != NULL) { if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS) coordinate_axis = glinterp->coordinate_axis; } switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glVertex3d(v->x, v->y, v->z); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glVertex3d(v->x, v->z, -v->y); break; } } /* * Called by V3DGLProcessModelExtra() to process a model of type * V3D_MODEL_TYPE_OTHER_DATA. * * Given inputs glres, glinterp, and m are assumed valid. */ static void V3DGLProcessModelOtherData( v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ) { int line_num; const char *line_ptr; for(line_num = 0; line_num < m->total_other_data_lines; line_num++) { line_ptr = (const char *)m->other_data_line[line_num]; if(line_ptr == NULL) continue; if(extra_cb != NULL) extra_cb(m, line_ptr, client_data); } } /* * Called by V3DGLProcessModelExtra() to process a model of type * V3D_MODEL_TYPE_STANDARD. * * Given inputs glres, glinterp, and m are assumed valid. */ static void V3DGLProcessModelStandard( v3d_glresource_struct *glres, v3d_glinterprite_struct *glinterp, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ) { int pn, line_num; const char *line_ptr; void *p; int matrix_level = 0; int texture_binded = FALSE; void *last_p_texture_orient = NULL; int coordinate_axis = V3D_GLCOORDINATE_AXIS_SCIENTIFIC; int flip_winding = FALSE; int pass_normals = V3D_GLPASS_NORMALS_AS_NEEDED; int unitlize_normals = TRUE; int pass_texcoords = V3D_GLPASS_TEXCOORDS_AS_NEEDED; int texture_name_case_sensitive = FALSE; int material_properties = V3D_GLPASS_MATERIAL_PROPERTIES_NEVER; int enable_blending = V3D_GLENABLE_BLENDING_NEVER; int faces = V3D_GLFACES_FRONT_AND_BACK; int blending_enabled = FALSE; int set_blend_func = FALSE; const char *heightfield_base_dir = NULL; const char *texture_base_dir = NULL; int last_begin_ptype = -1; mp_comment_struct *p_comment; mp_translate_struct *p_translate; mp_untranslate_struct *p_untranslate; mp_rotate_struct *p_rotate; mp_unrotate_struct *p_unrotate; mp_point_struct *p_point; mp_line_struct *p_line; mp_line_strip_struct *p_line_strip; mp_line_loop_struct *p_line_loop; mp_triangle_struct *p_triangle; mp_triangle_strip_struct *p_triangle_strip; mp_triangle_fan_struct *p_triangle_fan; mp_quad_struct *p_quad; mp_quad_strip_struct *p_quad_strip; mp_polygon_struct *p_polygon; mp_color_struct *p_color; mp_texture_select_struct *p_texture_select; mp_texture_orient_xy_struct *p_texture_orient_xy; mp_texture_orient_yz_struct *p_texture_orient_yz; mp_texture_orient_xz_struct *p_texture_orient_xz; mp_texture_off_struct *p_texture_off; mp_heightfield_load_struct *p_heightfield_load; /* Get some values GL interpritation structure (if set). */ if(glinterp->flags & V3D_GLFLAG_COORDINATE_AXIS) coordinate_axis = glinterp->coordinate_axis; if(glinterp->flags & V3D_GLFLAG_FLIP_WINDING) flip_winding = glinterp->flip_winding; if(glinterp->flags & V3D_GLFLAG_PASS_NORMALS) pass_normals = glinterp->pass_normals; if(glinterp->flags & V3D_GLFLAG_UNITLIZE_NORMALS) unitlize_normals = glinterp->unitlize_normals; if(glinterp->flags & V3D_GLFLAG_PASS_TEXCOORDS) pass_texcoords = glinterp->pass_texcoords; if(glinterp->flags & V3D_GLFLAG_TEXTURE_NAME_CASE_SENSITIVE) texture_name_case_sensitive = glinterp->texture_name_case_sensitive; if(glinterp->flags & V3D_GLFLAG_MATERIAL_PROPERTIES) material_properties = glinterp->material_properties; if(glinterp->flags & V3D_GLFLAG_FACES) faces = glinterp->faces; if(glinterp->flags & V3D_GLFLAG_ENABLE_BLENDING) enable_blending = glinterp->enable_blending; if(glinterp->flags & V3D_GLFLAG_SET_BLEND_FUNC) set_blend_func = glinterp->set_blend_func; if(glinterp->flags & V3D_GLFLAG_HEIGHTFIELD_BASE_DIR) heightfield_base_dir = glinterp->heightfield_base_dir; if(glinterp->flags & V3D_GLFLAG_TEXTURE_BASE_DIR) texture_base_dir = glinterp->texture_base_dir; /* Iterate through each primitive on the given editor. */ for(pn = 0; pn < m->total_primitives; pn++) { p = m->primitive[pn]; if(p == NULL) continue; /* Call glEnd() if last_begin_ptype does not match the * new primitive type. */ if((last_begin_ptype != V3DMPGetType(p)) && (last_begin_ptype > -1) ) { glEnd(); last_begin_ptype = -1; } /* Handle by primitive type. */ switch(V3DMPGetType(p)) { case V3DMP_TYPE_COMMENT: p_comment = (mp_comment_struct *)p; for(line_num = 0; line_num < p_comment->total_lines; line_num++) { line_ptr = (const char *)p_comment->line[line_num]; if(line_ptr == NULL) continue; if(extra_cb != NULL) extra_cb(m, line_ptr, client_data); } break; case V3DMP_TYPE_TRANSLATE: p_translate = (mp_translate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS) { if(!glinterp->allow_translations) break; } glPushMatrix(); matrix_level++; switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glTranslated( p_translate->x, p_translate->y, p_translate->z ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glTranslated( p_translate->x, p_translate->z, -p_translate->y ); break; } break; case V3DMP_TYPE_UNTRANSLATE: p_untranslate = (mp_untranslate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_TRANSLATIONS) { if(!glinterp->allow_translations) break; } glPopMatrix(); matrix_level--; break; case V3DMP_TYPE_ROTATE: p_rotate = (mp_rotate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS) { if(!glinterp->allow_rotations) break; } glPushMatrix(); matrix_level++; switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glRotated( -RADTODEG(p_rotate->heading), 0.0, 0.0, 1.0 ); glRotated( -RADTODEG(p_rotate->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_rotate->bank), 0.0, 1.0, 0.0 ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glRotated( -RADTODEG(p_rotate->heading), 0.0, 1.0, 0.0 ); glRotated( -RADTODEG(p_rotate->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_rotate->bank), 0.0, 0.0, 1.0 ); break; } break; case V3DMP_TYPE_UNROTATE: p_unrotate = (mp_unrotate_struct *)p; if(glinterp->flags & V3D_GLFLAG_ALLOW_ROTATIONS) { if(!glinterp->allow_rotations) break; } glPopMatrix(); matrix_level--; break; #define DO_SET_VERTEX_DYNAMIC \ { \ int i; \ mp_vertex_struct *v, *n, *tc; \ mp_vertex_struct *fbn = NULL; /* Fallback normal vector. */ \ \ /* Look for first non-empty fallback normal vector. */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ for(i = 0; i < V_TOTAL; i++) \ { \ n = P_PTR->n[i]; \ if(n != NULL) \ { \ if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \ fbn = n; \ } \ } \ } \ \ if(flip_winding) \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \ { \ n = P_PTR->n[V_TOTAL - 1]; \ if(n != NULL) \ { \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ } \ \ for(i = V_TOTAL - 1; i >= 0; i--) \ { \ v = P_PTR->v[i]; \ n = P_PTR->n[i]; \ tc = P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ else \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if((pass_normals != V3D_GLPASS_NORMALS_NEVER) && (V_TOTAL > 0)) \ { \ n = P_PTR->n[0]; \ if(n != NULL) \ { \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ } \ \ for(i = 0; i < V_TOTAL; i++) \ { \ v = P_PTR->v[i]; \ n = P_PTR->n[i]; \ tc = P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ } #define DO_SET_VERTEX_STATIC \ { \ int i; \ mp_vertex_struct *v, *n, *tc; \ mp_vertex_struct *fbn = NULL; /* Fallback normal vector. */ \ \ /* Look for first non-empty fallback normal vector. */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ for(i = 0; i < V_TOTAL; i++) \ { \ n = &P_PTR->n[i]; \ if(n != NULL) \ { \ if((n->x != 0.0) || (n->y != 0.0) || (n->z != 0.0)) \ fbn = n; \ } \ } \ } \ \ if(flip_winding) \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ n = &P_PTR->n[V_TOTAL - 1]; \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ \ for(i = V_TOTAL - 1; i >= 0; i--) \ { \ v = &P_PTR->v[i]; \ n = &P_PTR->n[i]; \ tc = &P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ else \ { \ /* Check if we need to set the fallback normal for the first \ * vertex. \ */ \ if(pass_normals != V3D_GLPASS_NORMALS_NEVER) \ { \ n = &P_PTR->n[0]; \ if((n->x == 0.0) && (n->y == 0.0) && (n->z == 0.0)) \ V3DGLSetNormal(glinterp, fbn); \ } \ \ for(i = 0; i < V_TOTAL; i++) \ { \ v = &P_PTR->v[i]; \ n = &P_PTR->n[i]; \ tc = &P_PTR->tc[i]; \ V3DGLSetNormal(glinterp, n); \ V3DGLSetTexCoord(glinterp, v, tc, texture_binded, last_p_texture_orient); \ V3DGLSetVertex(glinterp, v); \ } \ } \ } case V3DMP_TYPE_POINT: #define P_PTR p_point #define V_TOTAL V3DMP_POINT_NVERTEX P_PTR = (mp_point_struct *)p; if(last_begin_ptype != V3DMP_TYPE_POINT) glBegin(GL_POINTS); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_POINT; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE: #define P_PTR p_line #define V_TOTAL V3DMP_LINE_NVERTEX P_PTR = (mp_line_struct *)p; if(last_begin_ptype != V3DMP_TYPE_LINE) glBegin(GL_LINES); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_LINE; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE_STRIP: #define P_PTR p_line_strip #define V_TOTAL P_PTR->total P_PTR = (mp_line_strip_struct *)p; glBegin(GL_LINE_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_LINE_LOOP: #define P_PTR p_line_loop #define V_TOTAL P_PTR->total P_PTR = (mp_line_loop_struct *)p; glBegin(GL_LINE_LOOP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE: #define P_PTR p_triangle #define V_TOTAL V3DMP_TRIANGLE_NVERTEX P_PTR = (mp_triangle_struct *)p; if(last_begin_ptype != V3DMP_TYPE_TRIANGLE) glBegin(GL_TRIANGLES); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_TRIANGLE; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE_STRIP: #define P_PTR p_triangle_strip #define V_TOTAL P_PTR->total P_PTR = (mp_triangle_strip_struct *)p; glBegin(GL_TRIANGLE_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_TRIANGLE_FAN: #define P_PTR p_triangle_fan #define V_TOTAL P_PTR->total P_PTR = (mp_triangle_fan_struct *)p; glBegin(GL_TRIANGLE_FAN); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_QUAD: #define P_PTR p_quad #define V_TOTAL V3DMP_QUAD_NVERTEX P_PTR = (mp_quad_struct *)p; if(last_begin_ptype != V3DMP_TYPE_QUAD) glBegin(GL_QUADS); DO_SET_VERTEX_STATIC last_begin_ptype = V3DMP_TYPE_QUAD; #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_QUAD_STRIP: #define P_PTR p_quad_strip #define V_TOTAL P_PTR->total P_PTR = (mp_quad_strip_struct *)p; glBegin(GL_QUAD_STRIP); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; case V3DMP_TYPE_POLYGON: #define P_PTR p_polygon #define V_TOTAL P_PTR->total P_PTR = (mp_polygon_struct *)p; glBegin(GL_POLYGON); DO_SET_VERTEX_DYNAMIC glEnd(); #undef P_PTR #undef V_TOTAL break; #undef DO_SET_VERTEX_STATIC #undef DO_SET_VERTEX_DYNAMIC case V3DMP_TYPE_COLOR: p_color = (mp_color_struct *)p; if(p_color->a < 1.0) { if(enable_blending) { if(!blending_enabled) { glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); blending_enabled = TRUE; } } if(set_blend_func) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } } else { if(enable_blending) { if(blending_enabled) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); blending_enabled = FALSE; } } } /* Set color? */ if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_INSTEAD_COLOR) { glColor4d(p_color->r, p_color->g, p_color->b, p_color->a); } /* Set material properties? */ if(material_properties != V3D_GLPASS_MATERIAL_PROPERTIES_NEVER) { GLenum glface; GLfloat glparam[4]; switch(faces) { case V3D_GLFACES_FRONT_AND_BACK: glface = GL_FRONT_AND_BACK; break; case V3D_GLFACES_BACK: glface = GL_BACK; break; default: /* V3D_GLFACES_FRONT */ glface = GL_FRONT; break; } glparam[0] = (GLfloat)(p_color->ambient * p_color->r); glparam[1] = (GLfloat)(p_color->ambient * p_color->g); glparam[2] = (GLfloat)(p_color->ambient * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_AMBIENT, glparam); glparam[0] = (GLfloat)(p_color->diffuse * p_color->r); glparam[1] = (GLfloat)(p_color->diffuse * p_color->g); glparam[2] = (GLfloat)(p_color->diffuse * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_DIFFUSE, glparam); glparam[0] = (GLfloat)(p_color->specular * p_color->r); glparam[1] = (GLfloat)(p_color->specular * p_color->g); glparam[2] = (GLfloat)(p_color->specular * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_SPECULAR, glparam); glparam[0] = (GLfloat)(p_color->shininess * 128.0); glMaterialf(glface, GL_SHININESS, glparam[0]); glparam[0] = (GLfloat)(p_color->emission * p_color->r); glparam[1] = (GLfloat)(p_color->emission * p_color->g); glparam[2] = (GLfloat)(p_color->emission * p_color->b); glparam[3] = (GLfloat)(p_color->a); glMaterialfv(glface, GL_EMISSION, glparam); } break; case V3DMP_TYPE_TEXTURE_SELECT: p_texture_select = (mp_texture_select_struct *)p; if(p_texture_select->name != NULL) { const char *tex_name = (const char *)p_texture_select->name; int tn; v3d_texture_ref_struct *t; /* Previous last_p_texture_orient gets reset when * a new texture is binded. */ last_p_texture_orient = NULL; /* Iterate through each loaded texture on the * gl resources structure. */ for(tn = 0; tn < glres->total_textures; tn++) { t = glres->texture[tn]; if((t == NULL) ? 1 : (t->name == NULL)) continue; if(texture_name_case_sensitive) { if(!strcmp(t->name, tex_name)) break; } else { if(!strcasecmp(t->name, tex_name)) break; } } /* Matched texture? */ if(tn < glres->total_textures) t = glres->texture[tn]; else t = NULL; if(t == NULL) { /* No texture, unbind any existing texture. */ V3DTextureSelect(NULL); texture_binded = FALSE; } else { V3DTextureSelect(t); texture_binded = TRUE; } } break; case V3DMP_TYPE_TEXTURE_ORIENT_XY: p_texture_orient_xy = (mp_texture_orient_xy_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_ORIENT_YZ: p_texture_orient_yz = (mp_texture_orient_yz_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_ORIENT_XZ: p_texture_orient_xz = (mp_texture_orient_xz_struct *)p; if(texture_binded) { last_p_texture_orient = p; } break; case V3DMP_TYPE_TEXTURE_OFF: p_texture_off = (mp_texture_off_struct *)p; V3DTextureSelect(NULL); texture_binded = FALSE; last_p_texture_orient = NULL; break; case V3DMP_TYPE_HEIGHTFIELD_LOAD: p_heightfield_load = (mp_heightfield_load_struct *)p; if(p_heightfield_load->path != NULL) { int status, widthp, heightp; double x_spacing, y_spacing; const char *cstrptr; v3d_hf_options_struct hfopt; char tmp_path[PATH_MAX + NAME_MAX]; if(ISPATHABSOLUTE(p_heightfield_load->path)) { strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX); } else if(heightfield_base_dir != NULL) { cstrptr = (const char *)PrefixPaths( heightfield_base_dir, p_heightfield_load->path ); strncpy( tmp_path, (cstrptr == NULL) ? p_heightfield_load->path : cstrptr, PATH_MAX + NAME_MAX ); } else { strncpy(tmp_path, p_heightfield_load->path, PATH_MAX + NAME_MAX); } glPushMatrix(); switch(coordinate_axis) { case V3D_GLCOORDINATE_AXIS_GL: glTranslated( p_heightfield_load->x, p_heightfield_load->y, p_heightfield_load->z ); glRotated( -RADTODEG(p_heightfield_load->heading), 0.0, 0.0, 1.0 ); glRotated( -RADTODEG(p_heightfield_load->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->bank), 0.0, 1.0, 0.0 ); break; case V3D_GLCOORDINATE_AXIS_SCIENTIFIC: glTranslated( p_heightfield_load->x, p_heightfield_load->z, -p_heightfield_load->y ); glRotated( -RADTODEG(p_heightfield_load->heading), 0.0, 1.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->pitch), 1.0, 0.0, 0.0 ); glRotated( -RADTODEG(p_heightfield_load->bank), 0.0, 0.0, 1.0 ); break; } /* Set up heightfield options. */ hfopt.flags = (V3D_HF_OPT_FLAG_WINDING | V3D_HF_OPT_FLAG_SET_NORMAL | V3D_HF_OPT_FLAG_SET_TEXCOORD ); hfopt.winding = ((flip_winding) ? V3D_HF_WIND_CCW : V3D_HF_WIND_CW ); hfopt.set_normal = ((pass_normals != V3D_GLPASS_NORMALS_NEVER) ? V3D_HF_SET_NORMAL_AVERAGED : V3D_HF_SET_NORMAL_NEVER ); hfopt.set_texcoord = ((pass_texcoords != V3D_GLPASS_TEXCOORDS_NEVER) ? V3D_HF_SET_TEXCOORD_ALWAYS : V3D_HF_SET_TEXCOORD_NEVER ); /* Load heightfield from image file and generate GL * commands. */ status = V3DHFLoadFromFile( tmp_path, p_heightfield_load->x_length, p_heightfield_load->y_length, p_heightfield_load->z_length, &widthp, &heightp, &x_spacing, &y_spacing, NULL, /* No allocated z points. */ 0, /* GL list not important. */ &hfopt ); glPopMatrix(); } break; } } /* Need to call glEnd() if last_begin_ptype is not -1. */ if(last_begin_ptype > -1) { glEnd(); last_begin_ptype = -1; } /* Pop any extranous matrixes */ while(matrix_level > 0) { glPopMatrix(); matrix_level--; } /* Unbind any textures */ if(texture_binded) V3DTextureSelect(NULL); /* Restore blend state */ if(blending_enabled) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); blending_enabled = FALSE; } } /* * Interprites the given V3D model to GL commands. * * The correct GL context must be binded before calling this * function. */ void V3DGLProcessModelExtra( v3d_glresource_struct *glres, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ) { v3d_glinterprite_struct *glinterp; /* No model to process? */ if(m == NULL) return; /* Can't process without a GL resources structure. */ if(glres == NULL) return; glinterp = glres->glinterprite; if(glinterp == NULL) return; /* Handle by model type. */ switch(V3DModelGetType(m)) { case V3D_MODEL_TYPE_OTHER_DATA: V3DGLProcessModelOtherData( glres, glinterp, m, client_data, extra_cb ); break; case V3D_MODEL_TYPE_STANDARD: V3DGLProcessModelStandard( glres, glinterp, m, client_data, extra_cb ); break; } } /* * Simplified form of V3DGLProcessModelExtra() without the * extranous data callback. */ void V3DGLProcessModel( v3d_glresource_struct *glres, v3d_model_struct *m ) { V3DGLProcessModelExtra(glres, m, NULL, NULL); } searchandrescue_1.7.0/sar/cp.c0000664000175000001440000002402312046776373015345 0ustar jesseusers#include #include #include #ifdef __MSW__ # include #endif #include #include "gw.h" #include "v3dtex.h" #include "cpvalues.h" #include "cpins.h" #include "cp.h" time_t CPCurrentTime(ControlPanel *cp); CPIns *CPGetInsByNumber(ControlPanel *cp, int i); int CPAppendIns(ControlPanel *cp, CPIns *ins); ControlPanel *CPNew(gw_display_struct *display); void CPDelete(ControlPanel *cp); void CPSetPosition( ControlPanel *cp, GLfloat x, GLfloat y, GLfloat z /* In centimeters. */ ); void CPSetDirection( ControlPanel *cp, GLfloat heading, GLfloat pitch, GLfloat bank /* In radians. */ ); void CPSetSize( ControlPanel *cp, GLfloat width, GLfloat height /* In centimeters. */ ); void CPSetTexture(ControlPanel *cp, const char *path); void CPResetTimmers(ControlPanel *cp, time_t t); void CPChangeValues(ControlPanel *cp, ControlPanelValues *v); void CPDraw(ControlPanel *cp); void CPManage(ControlPanel *cp, ControlPanelValues *v); #ifndef PI # define PI 3.14159265 #endif #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? (float)atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) #define NORMAL3F(x,y,z) (glNormal3f( \ (GLfloat)(x), \ (GLfloat)(z), \ (GLfloat)-(y) \ )) #define TEXCOORD2F(x,y) (glTexCoord2f( \ (GLfloat)(x), \ (GLfloat)(y) \ )) #define VERTEX3F(x,y,z) (glVertex3f( \ (GLfloat)((x) / 100.0), \ (GLfloat)((z) / 100.0), \ (GLfloat)((y) / -100.0) \ )) #define ROTATEH(r) (glRotatef((GLfloat)-RADTODEG(r), \ 0.0f, 1.0f, 0.0f)) #define ROTATEP(r) (glRotatef((GLfloat)-RADTODEG(r), \ 1.0f, 0.0f, 0.0f)) #define ROTATEB(r) (glRotatef((GLfloat)-RADTODEG(r), \ 0.0f, 0.0f, 1.0f)) #define TRANSLATE(x,y,z) (glTranslatef( \ (GLfloat)((x) / 100.0), \ (GLfloat)((z) / 100.0), \ (GLfloat)((y) / -100.0) \ )) /* * Returns the current time in milliseconds. */ time_t CPCurrentTime(ControlPanel *cp) { const ControlPanelValues *v = CONTROL_PANEL_VALUES(cp); return((v != NULL) ? v->current_time : 0); } /* * Returns the instrument at index i. */ CPIns *CPGetInsByNumber(ControlPanel *cp, int i) { if(cp == NULL) return(NULL); if((i < 0) || (i >= cp->total_ins)) return(NULL); else return(cp->ins[i]); } /* * Appends the instrument to the control panel's list of * instruments, returning the new index or -1 on error. */ int CPAppendIns(ControlPanel *cp, CPIns *ins) { int i; if((cp == NULL) || (ins == NULL)) return(-1); i = MAX(cp->total_ins, 0); cp->total_ins = i + 1; cp->ins = (CPIns **)realloc( cp->ins, cp->total_ins * sizeof(CPIns *) ); if(cp->ins == NULL) { cp->total_ins = 0; return(-1); } cp->ins[i] = ins; return(i); } /* * Creates a new control panel. */ ControlPanel *CPNew(gw_display_struct *display) { ControlPanel *cp = CONTROL_PANEL(calloc(1, sizeof(ControlPanel))); if(cp == NULL) return(NULL); cp->display = display; cp->width = 100.0f; cp->height = 10.0f; return(cp); } /* * Deletes the control panel and all it's resources. */ void CPDelete(ControlPanel *cp) { int i; if(cp == NULL) return; /* Instruments. */ for(i = 0; i < cp->total_ins; i++) CPInsDelete(cp->ins[i]); free(cp->ins); cp->ins = NULL; cp->total_ins = 0; V3DTextureDestroy(cp->tex); cp->tex = NULL; free(cp); } /* * Set control panel position. */ void CPSetPosition( ControlPanel *cp, GLfloat x, GLfloat y, GLfloat z /* In centimeters. */ ) { if(cp == NULL) return; cp->x = x; cp->y = y; cp->z = z; } /* * Set control panel direction. */ void CPSetDirection( ControlPanel *cp, GLfloat heading, GLfloat pitch, GLfloat bank /* In radians. */ ) { if(cp == NULL) return; cp->heading = heading; cp->pitch = pitch; cp->bank = bank; } /* * Set control panel size. */ void CPSetSize( ControlPanel *cp, GLfloat width, GLfloat height /* In centimeters. */ ) { if(cp == NULL) return; cp->width = width; cp->height = height; } /* * Set control panel texture. */ void CPSetTexture(ControlPanel *cp, const char *path) { if(cp == NULL) return; V3DTextureDestroy(cp->tex); cp->tex = NULL; if((path != NULL) ? (*path == '\0') : GL_TRUE) return; cp->tex = V3DTextureLoadFromFile2DPreempt( path, "control_panel_tex", V3D_TEX_FORMAT_RGBA ); } /* * Resets all timmers on the control panel to t. */ void CPResetTimmers(ControlPanel *cp, time_t t) { int i; ControlPanelValues *v; if(cp == NULL) return; v = &cp->values; v->current_time = t; for(i = 0; i < cp->total_ins; i++) CPInsResetTimmers(cp->ins[i], t); } /* * Updates the values of the control panel and all its instruments. * * The GL frame buffer will be used to update the instrument's * textures. The viewport and other GL states will be modified to * accomidate this. */ void CPChangeValues(ControlPanel *cp, ControlPanelValues *v) { int i; ControlPanelValues *cpv; gw_display_struct *display = CONTROL_PANEL_DISPLAY(cp); if((display == NULL) || (v == NULL)) return; /* Set up GL states. */ cpv = CONTROL_PANEL_VALUES(cp); memcpy(cpv, v, sizeof(ControlPanelValues)); /* Instruments. */ for(i = 0; i < cp->total_ins; i++) CPInsChangeValues(cp->ins[i], v); } /* * Redraws the control panel and all its instruments. * * The model view translation should currently be at the center of * the cockpit. */ void CPDraw(ControlPanel *cp) { int i; gw_display_struct *display = CONTROL_PANEL_DISPLAY(cp); v3d_texture_ref_struct *tex; ControlPanelValues *v; if(display == NULL) return; v = CONTROL_PANEL_VALUES(cp); if(v == NULL) return; /* Set up GL states. */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); StateGLDisable(&display->state_gl, GL_LIGHTING); StateGLDisable(&display->state_gl, GL_BLEND); StateGLDisable(&display->state_gl, GL_FOG); StateGLDisable(&display->state_gl, GL_DEPTH_TEST); StateGLDepthFunc(&display->state_gl, GL_ALWAYS); StateGLEnable(&display->state_gl, GL_ALPHA_TEST); StateGLAlphaFunc(&display->state_gl, GL_GREATER, 0.5); StateGLShadeModel(&display->state_gl, GL_FLAT); StateGLEnable(&display->state_gl, GL_TEXTURE_2D); StateGLTexEnvI( &display->state_gl, GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); StateGLDisable(&display->state_gl, GL_CULL_FACE); StateGLDisable(&display->state_gl, GL_COLOR_MATERIAL); /* Draw fullscreen? */ if(v->fullscreen) { int width, height; GWContextGet( display, GWContextCurrent(display), NULL, NULL, NULL, NULL, &width, &height ); if((width > 1) && (height > 1) && (cp->width > 1) && (cp->height > 1) ) { CPRectangle rect; GWOrtho2DCoord( display, 0.0f, (float)(width - 1), 0.0f, (float)(height - 1) ); /* Calculate position and size of control panel in * window coordinates. */ rect.width = (GLfloat)width; rect.height = (GLfloat)width * cp->height / cp->width; rect.x = 0; rect.y = height - rect.height; /* Get control panel background texture and draw * background. */ tex = cp->tex; if(tex != NULL) { glColor3f(1.0f, 1.0f, 1.0f); V3DTextureSelect(tex); } else { glColor3f(0.0f, 0.0f, 0.0f); } glBegin(GL_QUADS); { glTexCoord2f(0, 0); glVertex2f(rect.x, rect.y); glTexCoord2f(0, 1); glVertex2f(rect.x, rect.y + rect.height - 1); glTexCoord2f(1, 1); glVertex2f(rect.x + rect.width - 1, rect.y + rect.height - 1); glTexCoord2f(1, 0); glVertex2f(rect.x + rect.width - 1, rect.y); } glEnd(); /* Instruments. */ for(i = 0; i < cp->total_ins; i++) CPInsDrawFullScreen(cp->ins[i], &rect); } } else { /* Draw 3d, so translate to control panel position. */ glPushMatrix(); TRANSLATE(cp->x, cp->y, cp->z); if(cp->heading != 0.0f) ROTATEH(cp->heading); if(cp->pitch != 0.0f) ROTATEP(cp->pitch); if(cp->bank != 0.0f) ROTATEB(cp->bank); /* Get control panel background texture and draw * background. */ tex = cp->tex; if(tex != NULL) { glColor3f(1.0f, 1.0f, 1.0f); V3DTextureSelect(tex); } else { glColor3f(0.0f, 0.0f, 0.0f); } glBegin(GL_QUADS); { NORMAL3F(0.0, 0.0, 1.0); TEXCOORD2F(0, 0); VERTEX3F(0.0, 0.0, 0.0); TEXCOORD2F(0, 1); VERTEX3F(0.0, -cp->height, 0.0); TEXCOORD2F(1, 1); VERTEX3F(cp->width, -cp->height, 0.0); TEXCOORD2F(1, 0); VERTEX3F(cp->width, 0.0, 0.0); } glEnd(); /* Instruments. */ for(i = 0; i < cp->total_ins; i++) CPInsDraw(cp->ins[i]); glPopMatrix(); } } /* * Manages the control panel and all its instruments. * * This function should be called once per loop. * * Only the members current_time and time_compensation in v are * used. */ void CPManage(ControlPanel *cp, ControlPanelValues *v) { int i; if((cp == NULL) || (v == NULL)) return; for(i = 0; i < cp->total_ins; i++) CPInsManage(cp->ins[i], v); } searchandrescue_1.7.0/sar/cmdclean.c0000664000175000001440000000331612046776403016505 0ustar jesseusers#include #include #include #include "../include/string.h" #include "gw.h" #include "obj.h" #include "objutils.h" #include "messages.h" #include "simop.h" #include "cmd.h" #include "sar.h" #include "config.h" void SARCmdClean(SAR_CMD_PROTOTYPE); #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? (float)atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define STRLEN(s) (((s) != NULL) ? ((int)strlen(s)) : 0) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) /* * Scene "cleaning" (deletion of effects objects). */ void SARCmdClean(SAR_CMD_PROTOTYPE) { int objects_deleted = 0; sar_core_struct *core_ptr = SAR_CORE(data); sar_scene_struct *scene = core_ptr->scene; if(scene == NULL) return; /* Delete all effects objects? */ if(!strcasecmp(arg, "all")) { objects_deleted = SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, -1, 0 ); } else { /* Delete effects objects relative to the player object */ objects_deleted = SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, scene->player_obj_num, 0 ); } if(SAR_CMD_IS_VERBOSE(flags)) { char *s = (char *)malloc( (80 + 80) * sizeof(char) ); sprintf( s, "%i object%s deleted.", objects_deleted, (objects_deleted != 1) ? "s" : "" ); SARMessageAdd(scene, s); free(s); } } searchandrescue_1.7.0/sar/Makefile.srclist0000664000175000001440000000507612046776414017724 0ustar jesseusersSRC_H = cmd.h config.h cp.h cpfio.h cpins.h \ cpinsaltimeter.h cpinsbearing.h cpinshorizon.h \ cpvalues.h explosion.h fire.h gctl.h gw.h horizon.h \ human.h image.h matrixmath.h menu.h messages.h \ mission.h missionio.h musiclistio.h obj.h objio.h \ objsound.h objutils.h optionio.h playerstatio.h sar.h \ sarcamp.h \ sardraw.h sardrawdefs.h sardrawpm.h sardrawselect.h \ sarfio.h sarfps.h sarinstall.h sarkey.h sarmemory.h \ sarmenubuild.h sarmenucb.h sarmenucodes.h \ sarmenumanage.h sarmenuop.h sarmenuoptions.h sarmusic.h \ sarreality.h sarscreenshot.h sarsimbegin.h sarsimend.h \ sarsplash.h sartime.h sceneio.h scenesound.h sfm.h \ sfmmodel.h \ sfmtypes.h simcb.h simcontact.h simmanage.h simop.h \ simsurface.h simutils.h smoke.h sound.h stategl.h \ text3d.h textinput.h texturelistio.h v3dfio.h v3dgl.h \ v3dhf.h v3dmh.h v3dmodel.h v3dmp.h v3dtex.h weather.h \ x3d.h SRC_C = cmd.c cmdclean.c cmdfire.c cmdmemory.c \ cmdoption.c cmdset.c cmdsmoke.c cmdtime.c cp.c cpfio.c \ cpins.c cpinsaltimeter.c cpinsbearing.c cpinshorizon.c \ explosion.c fire.c gctl.c gwx.c gwx_dialog.c horizon.c \ human.c humanio.c image.c main.c matrixmath.c menu.c \ menumap.c menuobjview.c messages.c mission.c \ missionio.c musiclistio.c objio.c objiopremodeled.c \ objsound.c objutils.c optionio.c playerstatio.c \ sarcamp.c \ sardraw.c sardrawhelipad.c \ sardrawhuman.c sardrawmessages.c sardrawpm.c \ sardrawpm_building.c sardrawpm_controltower.c \ sardrawpm_ptt.c sardrawpm_radiotower.c \ sardrawpm_tower.c sardrawrunway.c sardrawselect.c \ sardrawutils.c sarfio.c sarfioopen.c sarfiosave.c \ sarinstall.c sarkey.c sarmemory.c sarmenubuild.c \ sarmenucb.c sarmenumanage.c sarmenuop.c \ sarmenuoptions.c sarmusic.c sarscreenshot.c \ sarsimbegin.c sarsimend.c sarsplash.c sartime.c \ sarutils.c sceneio.c scenesound.c sfm.c sfmmath.c \ sfmmodel.c sfmsimforce.c simcb.c simcontact.c \ simmanage.c simop.c simsurface.c simutils.c smoke.c \ sound.c stategl.c text3d.c textinput.c texturelistio.c \ v3dfio.c v3dgl.c v3dhf.c v3dmh.c v3dmodel.c v3dmp.c \ v3dtex.c weather.c weatherio.c x3d.c SRC_CPP = disk.cpp fio.cpp gww.cpp string.cpp strexp.cpp \ tga.cpp tgadither.cpp searchandrescue_1.7.0/sar/sardrawpm.c0000664000175000001440000000261412046776373016745 0ustar jesseusers#include #include #include #ifdef __MSW__ # include #endif #include #include #include "gw.h" #include "sarreality.h" #include "obj.h" #include "objutils.h" #include "sfm.h" #include "sar.h" #include "sardraw.h" #include "sardrawpm.h" #include "sardrawdefs.h" void SARDrawPremodeled(SAR_DRAW_PREMODELED_PROTOTYPE); /* * Front end to drawing premodeled objects, called by SARDraw(). */ void SARDrawPremodeled(SAR_DRAW_PREMODELED_PROTOTYPE) { if((dc == NULL) || (obj_ptr == NULL) || (obj_premodeled_ptr == NULL)) return; #define SAR_DRAW_PREMODELED_INPUT \ dc, obj_ptr, obj_premodeled_ptr, \ camera_dist, draw_for_gcc switch(obj_premodeled_ptr->type) { case SAR_OBJ_PREMODELED_BUILDING: SARDrawPremodeledBuilding(SAR_DRAW_PREMODELED_INPUT); break; case SAR_OBJ_PREMODELED_CONTROL_TOWER: SARDrawPremodeledControlTower(SAR_DRAW_PREMODELED_INPUT); break; case SAR_OBJ_PREMODELED_HANGAR: /* TODO */ break; case SAR_OBJ_PREMODELED_POWER_TRANSMISSION_TOWER: SARDrawPremodeledPowerTransmissionTower(SAR_DRAW_PREMODELED_INPUT); break; case SAR_OBJ_PREMODELED_TOWER: SARDrawPremodeledTower(SAR_DRAW_PREMODELED_INPUT); break; case SAR_OBJ_PREMODELED_RADIO_TOWER: SARDrawPremodeledRadioTower(SAR_DRAW_PREMODELED_INPUT); break; } #undef SAR_DRAW_PREMODELED_INPUT } searchandrescue_1.7.0/sar/sardrawselect.h0000664000175000001440000000167612046776404017617 0ustar jesseusers#ifndef SARDRAWSELECT_H #define SARDRAWSELECT_H #include #include "sar.h" /* Select processing used by SARDrawMap() */ extern void SARDrawMapProcessHits( sar_core_struct *core_ptr, GLint hits, GLuint buffer[] ); extern int SARDrawMapObjNameListAppend( sar_drawmap_objname_struct ***ptr, int *total, GLuint gl_name, const char *obj_name ); extern void SARDrawMapObjNameListDelete( sar_drawmap_objname_struct ***ptr, int *total ); /* Ground contact check hit list */ extern int *SARGetGCCHitList( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, int obj_num, int *hits ); /* Ground contact check if over water */ extern int SARGetGHCOverWater( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, int obj_num, Boolean *got_hit, Boolean *over_water ); #endif /* SARDRAWSELECT_H */ searchandrescue_1.7.0/sar/textinput.c0000664000175000001440000003101412046776377017011 0ustar jesseusers#include #include #include #include #ifdef __MSW__ # include #endif #include #include "../include/string.h" #include "gw.h" #include "stategl.h" #include "textinput.h" static void SARTextInputHistoryRecord( text_input_struct *p, const char *value ); text_input_struct *SARTextInputNew( gw_display_struct *display, GWFont *font ); void SARTextInputDelete(text_input_struct *p); static void SARTextInputCharInsert(text_input_struct *p, char c); static void SARTextInputCharBackspace(text_input_struct *p); static void SARTextInputCharDelete(text_input_struct *p); void SARTextInputHandleKey( text_input_struct *p, int k, Boolean state ); void SARTextInputHandlePointer( text_input_struct *p, int x, int y, gw_event_type type, int btn_num ); Boolean SARTextInputIsMapped(text_input_struct *p); void SARTextInputMap( text_input_struct *p, const char *label, const char *value, void (*func_cb)(const char *, void *), void *data ); void SARTextInputUnmap(text_input_struct *p); void SARTextInputDraw(text_input_struct *p); #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define STRLEN(s) (((s) != NULL) ? ((int)strlen(s)) : 0) /* * Records the given value on to the prompt's list of history * values. */ static void SARTextInputHistoryRecord( text_input_struct *p, const char *value ) { int i, max = 5; if((p == NULL) || (value == NULL)) return; if(p->total_history < max) { /* Allocate one more pointer */ i = MAX(p->total_history, 0); p->total_history = i + 1; p->history = (char **)realloc( p->history, p->total_history * sizeof(char *) ); if(p->history == NULL) { p->total_history = 0; return; } /* Shift pointers */ for(; i >= 1; i--) p->history[i] = p->history[i - 1]; /* Add new value */ i = 0; if(i < p->total_history) p->history[i] = STRDUP(value); } else { /* Delete oldest (highest) index value */ i = p->total_history - 1; if(i >= 0) free(p->history[i]); /* Shift pointers */ for(; i >= 1; i--) p->history[i] = p->history[i - 1]; /* Add new value */ i = 0; if(i < p->total_history) p->history[i] = STRDUP(value); } } /* * Create a new text input prompt. */ text_input_struct *SARTextInputNew( gw_display_struct *display, GWFont *font ) { text_input_struct *p = TEXT_INPUT(calloc( 1, sizeof(text_input_struct) )); if(p == NULL) return(NULL); p->display = display; p->font = font; p->label = NULL; p->buf = NULL; p->len = 0; p->pos = 0; p->last_value_x = 0; p->last_value_y = 0; p->data = NULL; p->func_cb = NULL; p->history = NULL; p->total_history = 0; p->last_history_num = -1; return(p); } /* * Deletes the text input prompt. */ void SARTextInputDelete(text_input_struct *p) { int i; if(p == NULL) return; for(i = 0; i < p->total_history; i++) free(p->history[i]); free(p->history); free(p->label); free(p->buf); free(p); } /* * Insert character. */ static void SARTextInputCharInsert(text_input_struct *p, char c) { int i, n; char *buf; if(!isprint(c)) return; /* Increase buffer allocation */ i = MAX(p->len, 0); p->len = i + 1; p->buf = buf = (char *)realloc( p->buf, (p->len + 1) * sizeof(char) ); if(buf == NULL) { p->len = p->pos = 0; return; } /* Sanitize position */ if(p->pos >= p->len) p->pos = p->len - 1; if(p->pos < 0) p->pos = 0; /* Shift buffer at position */ for(i = p->len - 1, n = p->pos; i > n; i--) buf[i] = buf[i - 1]; buf[p->len] = '\0'; /* Insert new character */ buf[p->pos] = c; /* Increment position */ p->pos++; } /* * Backspace. */ static void SARTextInputCharBackspace(text_input_struct *p) { int i; char *buf = p->buf; if((buf == NULL) || (p->pos <= 0)) return; /* Reduce buffer one character left of current position */ for(i = p->pos - 1; i < p->len; i++) buf[i] = buf[i + 1]; /* Move position one character to the left */ p->pos--; /* Reduce buffer allocation */ p->len--; if(p->len < 0) p->len = 0; p->buf = (char *)realloc( p->buf, (p->len + 1) * sizeof(char) ); if(p->buf == NULL) { p->len = p->pos = 0; return; } } /* * Delete. */ static void SARTextInputCharDelete(text_input_struct *p) { int i; char *buf = p->buf; if((buf == NULL) || (p->pos >= p->len)) return; /* Reduce buffer at current position */ for(i = MAX(p->pos, 0); i < p->len; i++) buf[i] = buf[i + 1]; /* Reduce buffer allocation */ p->len--; if(p->len < 0) p->len = 0; p->buf = (char *)realloc( p->buf, (p->len + 1) * sizeof(char) ); if(p->buf == NULL) { p->len = p->pos = 0; return; } } /* * Handles key event if prompt is mapped. */ void SARTextInputHandleKey( text_input_struct *p, int k, Boolean state ) { int events_handled = 0; Boolean ctrl, shift; gw_display_struct *display = (p != NULL) ? p->display : NULL; if(!SARTextInputIsMapped(p) || (display == NULL) || !state ) return; /* Get modifier keys */ ctrl = display->ctrl_key_state; shift = display->shift_key_state; /* Handle key */ switch(k) { case 0x1b: /* Escape */ /* Unmap prompt, delete value, and unset callback * function. */ if(p->func_cb != NULL) { void (*func_cb)(const char *, void *) = p->func_cb; void *data = p->data; /* Unmap prompt, delete value, and unset * callback function. */ SARTextInputUnmap(p); /* Call function callback */ func_cb(NULL, data); } events_handled++; break; case GWKeyUp: if(p->history != NULL) { int i = MAX(p->last_history_num + 1, 0); if((i >= 0) && (i < p->total_history)) { free(p->buf); p->buf = STRDUP(p->history[i]); p->len = STRLEN(p->buf); p->pos = p->len; p->last_history_num = i; } } events_handled++; break; case GWKeyDown: if(p->history != NULL) { int i = p->last_history_num - 1; if((i >= 0) && (i < p->total_history)) { free(p->buf); p->buf = STRDUP(p->history[i]); p->len = STRLEN(p->buf); p->pos = p->len; p->last_history_num = i; } } events_handled++; break; case GWKeyLeft: /* Move position to the left */ p->pos--; if(p->pos < 0) p->pos = 0; events_handled++; break; case GWKeyRight: /* Move position to the right */ p->pos++; if(p->pos > p->len) p->pos = p->len; events_handled++; break; case GWKeyHome: /* Move position to beginning */ p->pos = 0; events_handled++; break; case GWKeyEnd: /* Move position to end (past the value's last character */ p->pos = p->len; events_handled++; break; case GWKeyBackSpace: /* Backspace */ SARTextInputCharBackspace(p); events_handled++; break; case GWKeyDelete: /* Delete (or backspace if shift modifier key is held) */ if(shift) SARTextInputCharBackspace(p); else SARTextInputCharDelete(p); events_handled++; break; case '\n': /* Enter */ /* Call callback function and then unmap prompt */ if(p->func_cb != NULL) { /* We need to make a copy of the value and record * the function pointer since both values on the * prompt structure p will be deleted during the * prompt unmap (which occures first) before the * function callback is called. */ void (*func_cb)(const char *, void *) = p->func_cb; char *value = STRDUP(p->buf); void *data = p->data; /* Record this history value */ SARTextInputHistoryRecord(p, value); /* Reset last recalled history value index number */ p->last_history_num = -1; /* Unmap prompt, delete value, and unset * callback function. */ SARTextInputUnmap(p); /* Call function callback using the coppied value */ func_cb(value, data); /* Deallocate value */ free(value); events_handled++; } break; default: /* Insert a character */ SARTextInputCharInsert( p, (char)(shift ? toupper(k) : k) ); events_handled++; break; } } /* * Handles pointer event if prompt is mapped. */ void SARTextInputHandlePointer( text_input_struct *p, int x, int y, gw_event_type type, int btn_num ) { int events_handled = 0; int fw, fh; gw_display_struct *display = (p != NULL) ? p->display : NULL; GWFont *font = (p != NULL) ? p->font : NULL; if(!SARTextInputIsMapped(p) || (display == NULL)) return; GWGetFontSize(font, NULL, NULL, &fw, &fh); /* Pointer event in y axis bounds? */ if((events_handled == 0) && (y >= p->last_value_y) && (y < (p->last_value_y + fh)) ) { /* Handle by event type */ switch(type) { case GWEventTypeButtonPress: case GWEventTypeButtonRelease: if(btn_num == 1) { int pos = (int)((fw > 0) ? ((x - p->last_value_x) / fw) : 0 ); if(pos > p->len) pos = p->len; if(pos < 0) pos = 0; p->pos = pos; events_handled++; } break; case GWEventTypePointerMotion: case GWEventType2ButtonPress: case GWEventType3ButtonPress: break; } } } /* * Chefcks if the text input prompt is mapped by checking if its * function callback is set. */ Boolean SARTextInputIsMapped(text_input_struct *p) { return((p != NULL) ? (p->func_cb != NULL) : False); } /* * Maps the text input prompt and sets it's label, value, and * function callback. */ void SARTextInputMap( text_input_struct *p, const char *label, const char *value, void (*func_cb)(const char *, void *), void *data ) { if(p == NULL) return; free(p->label); p->label = STRDUP(label); if(value != NULL) { free(p->buf); p->buf = STRDUP(value); p->len = p->pos = STRLEN(p->buf); } else { free(p->buf); p->buf = NULL; p->len = p->pos = 0; } p->func_cb = func_cb; p->data = data; } /* * Unmaps the text input prompt, deleting the value and unsetting * the function callback. */ void SARTextInputUnmap(text_input_struct *p) { if(p == NULL) return; free(p->label); p->label = NULL; free(p->buf); p->buf = NULL; p->len = 0; p->pos = 0; p->data = NULL; p->func_cb = NULL; } /* * Draws text input prompt. */ void SARTextInputDraw(text_input_struct *p) { const char *label, *buf; int label_len, buf_len, pos, len; int x0, y0, xc, yc, fw, fh; int width, height; StateGLBoolean alpha_test; gw_display_struct *display = (p != NULL) ? p->display : NULL; GWFont *font = (p != NULL) ? p->font : NULL; if(!SARTextInputIsMapped(p) || (display == NULL) || (font == NULL) ) return; GWContextGet( display, GWContextCurrent(display), NULL, NULL, NULL, NULL, &width, &height ); if((width <= 0) || (height <= 0)) return; GWGetFontSize(font, NULL, NULL, &fw, &fh); pos = p->pos; label = p->label; buf = p->buf; label_len = STRLEN(label); buf_len = STRLEN(buf); /* Calculat4 starting coordinates, use length of buffer plus * tolorence and additional characters (7 more chars). */ len = (label_len + buf_len + 7) * fw; if(len > width) x0 = width - len; else x0 = (width / 2) - (len / 2); y0 = (int)(0.5 * height); xc = x0; yc = y0; /* Draw shaded background */ alpha_test = display->state_gl.alpha_test; StateGLDisable(&display->state_gl, GL_ALPHA_TEST); StateGLEnable(&display->state_gl, GL_BLEND); StateGLBlendFunc( &display->state_gl, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glBegin(GL_QUADS); { glColor4d(0.0, 0.0, 0.0, 0.5); glVertex2d(0, yc - fh - 2); glVertex2d(width, yc - fh - 2); glVertex2d(width, yc + 2); glVertex2d(0, yc + 2); } glEnd(); StateGLDisable(&display->state_gl, GL_BLEND); if(alpha_test) StateGLEnable(&display->state_gl, GL_ALPHA_TEST); /* Set text color and font */ glColor4d(1.0, 1.0, 1.0, 1.0); GWSetFont(display, font); /* Draw label */ GWDrawString(display, xc, yc, label); xc += (label_len * fw); /* Draw deliminator */ GWDrawString(display, xc, yc, ": "); xc += (2 * fw); /* At this poin we need to record the position of the start * of the value (upper left corner in window coordinates) * for use by other functions. */ p->last_value_x = xc; p->last_value_y = yc; /* Draw value and cursor */ GWDrawString(display, xc, yc, buf); GWDrawString(display, xc + (pos * fw), yc, "_"); } searchandrescue_1.7.0/sar/cpfio.c0000664000175000001440000004406512046776376016056 0ustar jesseusers#include #include #include #include #include #ifdef __MSW__ # include #endif #include "../include/string.h" #include "../include/disk.h" #include "../include/fio.h" #include #include "gw.h" #include "v3dtex.h" #include "cpvalues.h" #include "cpins.h" #include "cpinsaltimeter.h" #include "cpinsbearing.h" #include "cpinshorizon.h" #include "cp.h" #include "cpfio.h" #include "config.h" static int CPLoadInstrumentAltimeter( FILE *fp, CPIns *ins, const char *parm ); static int CPLoadInstrumentBearing( FILE *fp, CPIns *ins, const char *parm ); static int CPLoadInstrumentHorizon( FILE *fp, CPIns *ins, const char *parm ); static int CPLoadInstrumentFromFile( ControlPanel *cp, const char *path, CPIns *ins, int ins_num, const char *filename ); int CPLoadFromFile(ControlPanel *cp, const char *path); #ifndef PI # define PI 3.14159265 #endif #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? (float)atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) /* * Altimeter instrument specific loading, called by * CPLoadInstrumentFromFile(). */ static int CPLoadInstrumentAltimeter( FILE *fp, CPIns *ins, const char *parm ) { /* CPInsAltimeter *insv = CPINS_ALTIMETER(ins); */ int handled_parm = 0; return(handled_parm); } /* * Bearing instrument specific loading, called by * CPLoadInstrumentFromFile(). */ static int CPLoadInstrumentBearing( FILE *fp, CPIns *ins, const char *parm ) { CPInsBearing *insv = CPINS_BEARING(ins); int handled_parm = 0; /* BearingMagneticVelocityDecceleration */ if(!strcasecmp(parm, "BearingMagneticVelocityDecceleration") || !strcasecmp(parm, "BearingMagneticVelocityDeccel") ) { double vf[1]; FGetValuesF(fp, vf, 1); insv->bearing_mag_vel_dec = (float)DEGTORAD( MAX(vf[0], 1.0) ); handled_parm++; } return(handled_parm); } /* * Horizon instrument specific loading, called by * CPLoadInstrumentFromFile(). */ static int CPLoadInstrumentHorizon( FILE *fp, CPIns *ins, const char *parm ) { CPInsHorizon *insv = CPINS_HORIZON(ins); int handled_parm = 0; /* DegreesVisible */ if(!strcasecmp(parm, "DegreesVisible")) { double vf[1]; FGetValuesF(fp, vf, 1); insv->deg_visible = (int)MAX(vf[0], 1.0); handled_parm++; } /* BankNotchRadius */ else if(!strcasecmp(parm, "BankNotchRadius")) { double vf[1]; FGetValuesF(fp, vf, 1); insv->bank_notch_radius = (float)vf[0]; handled_parm++; } return(handled_parm); } /* * Called by CPLoadFromFile(). * * Loads an instrument configuration file that will set up values * specific to that instrument. * * Returns non-zero on error. */ static int CPLoadInstrumentFromFile( ControlPanel *cp, const char *path, CPIns *ins, int ins_num, const char *filename ) { int handled_parm; FILE *fp; char *buf = NULL; struct stat stat_buf; if((cp == NULL) || (filename == NULL)) return(-1); if(*filename == '\0') return(-1); /* No instrument in context? */ if(ins == NULL) { fprintf(stderr, "%s: No instrument in context.\n", filename); return(-1); } /* Check if file exists. */ if(stat(filename, &stat_buf)) { fprintf(stderr, "%s: No such file.\n", filename); return(-1); } /* Open instrument configuration file. */ fp = FOpen(filename, "rb"); if(fp == NULL) { fprintf(stderr, "%s: Cannot open.\n", filename); return(-1); } /* Begin reading instruent configuration file. */ do { buf = FSeekNextParm( fp, buf, SAR_COMMENT_CHAR, SAR_CFG_DELIM_CHAR ); if(buf == NULL) break; handled_parm = 0; /* Version */ if(!strcasecmp(buf, "Version")) { double vf[2]; FGetValuesF(fp, vf, 2); /* Ignore. */ handled_parm++; } /* Resolution */ else if(!strcasecmp(buf, "Resolution")) { int res_width, res_height; double vf[2]; FGetValuesF(fp, vf, 2); res_width = (int)vf[0]; res_height = (int)vf[1]; if(res_width < 2) { fprintf( stderr, "%s: Resolution: Error: Width %i cannot be less than 2 (must be a 2^x value).\n", filename, res_width ); res_width = 2; } if(res_height < 2) { fprintf( stderr, "%s: Resolution: Error: Height %i cannot be less than 2 (must be a 2^x value).\n", filename, res_height ); res_width = 2; } CPInsSetResolution(ins, res_width, res_height); handled_parm++; } /* TextureBackground */ else if(!strcasecmp(buf, "TextureBackground") || !strcasecmp(buf, "TextureBG") ) { char *s = FGetString(fp); if(!ISPATHABSOLUTE(s)) { char *s2 = STRDUP(PrefixPaths(path, s)); free(s); s = s2; } CPInsSetTextureBG(ins, s); free(s); handled_parm++; } /* TextureForeground */ else if(!strcasecmp(buf, "TextureForeground") || !strcasecmp(buf, "TextureFG") ) { char *s = FGetString(fp); if(!ISPATHABSOLUTE(s)) { char *s2 = STRDUP(PrefixPaths(path, s)); free(s); s = s2; } CPInsSetTextureFG(ins, s); free(s); handled_parm++; } /* ColorBackgroundNormal */ else if(!strcasecmp(buf, "ColorBackgroundNormal") || !strcasecmp(buf, "ColorBGNormal") ) { CPColor *c = &ins->color_bg[CP_COLOR_STATE_NORMAL]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorBackgroundDim */ else if(!strcasecmp(buf, "ColorBackgroundDim") || !strcasecmp(buf, "ColorBGDim") ) { CPColor *c = &ins->color_bg[CP_COLOR_STATE_DIM]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorBackgroundDark */ else if(!strcasecmp(buf, "ColorBackgroundDark") || !strcasecmp(buf, "ColorBGDark") ) { CPColor *c = &ins->color_bg[CP_COLOR_STATE_DARK]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorBackgroundLighted */ else if(!strcasecmp(buf, "ColorBackgroundLighted") || !strcasecmp(buf, "ColorBGLighted") ) { CPColor *c = &ins->color_bg[CP_COLOR_STATE_LIGHTED]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorForegroundNormal */ else if(!strcasecmp(buf, "ColorForegroundNormal") || !strcasecmp(buf, "ColorFGNormal") ) { CPColor *c = &ins->color_fg[CP_COLOR_STATE_NORMAL]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorForegroundDim */ else if(!strcasecmp(buf, "ColorForegroundDim") || !strcasecmp(buf, "ColorFGDim") ) { CPColor *c = &ins->color_fg[CP_COLOR_STATE_DIM]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorForegroundDark */ else if(!strcasecmp(buf, "ColorForegroundDark") || !strcasecmp(buf, "ColorFGDark") ) { CPColor *c = &ins->color_fg[CP_COLOR_STATE_DARK]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorForegroundLighted */ else if(!strcasecmp(buf, "ColorForegroundLighted") || !strcasecmp(buf, "ColorFGLighted") ) { CPColor *c = &ins->color_fg[CP_COLOR_STATE_LIGHTED]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorTextNormal */ else if(!strcasecmp(buf, "ColorTextNormal")) { CPColor *c = &ins->color_text[CP_COLOR_STATE_NORMAL]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorTextDim */ else if(!strcasecmp(buf, "ColorTextDim")) { CPColor *c = &ins->color_text[CP_COLOR_STATE_DIM]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorTextDark */ else if(!strcasecmp(buf, "ColorTextDark")) { CPColor *c = &ins->color_text[CP_COLOR_STATE_DARK]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* ColorTextLighted */ else if(!strcasecmp(buf, "ColorTextLighted")) { CPColor *c = &ins->color_text[CP_COLOR_STATE_LIGHTED]; double vf[3]; FGetValuesF(fp, vf, 3); c->r = (GLfloat)CLIP(vf[0], 0.0, 1.0); c->g = (GLfloat)CLIP(vf[1], 0.0, 1.0); c->b = (GLfloat)CLIP(vf[2], 0.0, 1.0); handled_parm++; } /* If the parameter was not handled then pass it to an * instrument specific handler. */ if(handled_parm <= 0) { /* Call instrument specific loading function to * deal with this parameter. */ switch(CPINS_TYPE(ins)) { case CPINS_TYPE_ALTIMETER: handled_parm += CPLoadInstrumentAltimeter( fp, ins, buf ); break; case CPINS_TYPE_BEARING: handled_parm += CPLoadInstrumentBearing( fp, ins, buf ); break; case CPINS_TYPE_HORIZON: handled_parm += CPLoadInstrumentHorizon( fp, ins, buf ); break; } /* Parameter still not handled? */ if(handled_parm <= 0) { fprintf( stderr, "%s: Unsupported parameter `%s'.\n", filename, buf ); FSeekNextLine(fp); } } } while(1); /* Close instrument configuration file. */ FClose(fp); return(0); } /* * Loads control panel from file. * * The given path must be a prefix to the control panel directory * (not an actual file). The appropriate files will be loaded * in the directory specified by path. * * Returns non-zero on error. */ int CPLoadFromFile(ControlPanel *cp, const char *path) { FILE *fp; char *buf = NULL; char *cp_file, *cp_tex_file; struct stat stat_buf; int ins_num = -1; CPIns *ins = NULL; if((cp == NULL) || (path == NULL)) return(-1); if(*path == '\0') return(-1); if(stat(path, &stat_buf)) { fprintf( stderr, "%s: No such directory.\n", path ); return(-1); } /* Get file names. */ /* Control panel configuration file. */ cp_file = STRDUP( PrefixPaths(path, SAR_DEF_INSTRUMENTS_FILE) ); /* Control panel texture. */ cp_tex_file = STRDUP( PrefixPaths(path, SAR_DEF_CONTROL_PANEL_TEX_FILE) ); #define DO_FREE_LOCALS { \ free(cp_file); \ free(cp_tex_file); \ } /* Check if required files exist. */ if(stat(cp_file, &stat_buf)) { fprintf(stderr, "%s: No such file.\n", cp_file); DO_FREE_LOCALS return(-1); } /* Open control panel configuration file. */ fp = FOpen(cp_file, "rb"); if(fp == NULL) { fprintf(stderr, "%s: Cannot open.\n", cp_file); DO_FREE_LOCALS return(-1); } /* Begin reading control panel configuration file. */ do { buf = FSeekNextParm( fp, buf, SAR_COMMENT_CHAR, SAR_CFG_DELIM_CHAR ); if(buf == NULL) break; /* Begin handling parameter. */ /* Version */ if(!strcasecmp(buf, "Version")) { double vf[2]; FGetValuesF(fp, vf, 2); /* Ignore. */ } /* InstrumentNew */ else if(!strcasecmp(buf, "InstrumentNew")) { char *type = FGetString(fp); /* Create new instrument by the given type. */ if(!strcasecmp(type, "Instrument")) { ins = CPInsNew(sizeof(CPIns), cp, CPINS_TYPE_INS, type); } /* Altimeter */ else if(!strcasecmp(type, "Altimeter")) { ins = CPInsAltimeterNew(cp); } /* Bearing */ else if(!strcasecmp(type, "Bearing")) { ins = CPInsBearingNew(cp); } /* Artificial Horizon */ else if(!strcasecmp(type, "ArtificialHorizon") || !strcasecmp(type, "Horizon") ) { ins = CPInsHorizonNew(cp); } else { fprintf( stderr, "%s: InstrumentNew: Unsupported instrument type \"%s\".\n", cp_file, type ); ins = NULL; ins_num = -1; } /* Created new instrument successfully? */ if(ins != NULL) { ins_num = CPAppendIns(cp, ins); if(ins_num < 0) fprintf( stderr, "%s: InstrumentNew: Error appending instrument type \"%s\" to control panel.\n", cp_file, type ); } free(type); } /* Position */ else if(!strcasecmp(buf, "Position")) { double vf[2]; FGetValuesF(fp, vf, 2); /* Set instrument position coefficient relative to the * control panel's upper left corner. */ CPInsSetPosition( ins, (GLfloat)vf[0], (GLfloat)vf[1] ); } /* Size */ else if(!strcasecmp(buf, "Size")) { double vf[2]; FGetValuesF(fp, vf, 2); /* Set instrument size coefficient. */ CPInsSetSize( ins, (GLfloat)vf[0], (GLfloat)vf[1] ); } /* ConfigurationFile */ else if(!strcasecmp(buf, "ConfigurationFile")) { char *ins_file = FGetString(fp); if(!ISPATHABSOLUTE(ins_file)) { char *s = STRDUP( PrefixPaths(path, ins_file) ); free(ins_file); ins_file = s; } CPLoadInstrumentFromFile( cp, path, ins, ins_num, ins_file ); free(ins_file); } else { fprintf( stderr, "%s: Unsupported parameter `%s'.\n", cp_file, buf ); FSeekNextLine(fp); } } while(1); /* Close control panel configuration file. */ FClose(fp); /* Load control panel texture. */ CPSetTexture(cp, cp_tex_file); DO_FREE_LOCALS #undef DO_FREE_LOCALS return(0); } searchandrescue_1.7.0/sar/runway/0000755000175000001440000000000010104532745016103 5ustar jesseuserssearchandrescue_1.7.0/sar/runway/README0000664000175000001440000000004512046776420016773 0ustar jesseusersCompile time 3D objects for runways. searchandrescue_1.7.0/sar/runway/runway_td_markers.x3d0000664000175000001440000000226212046776420022276 0ustar jesseusersstatic char *runway_td_markers_x3d[] = { "X3D Model File", "", "camera 0.444056 -1.454843 0.860000 -0.308876 0.824971 -0.473306 0.698132 0.010000 1000000.000000", "", "begin_quads", "normal3f 0.000000 0.000000 1.000000", "vertex3f -0.195351 0.500000 0.000000", "vertex3f -0.195351 -0.500000 0.000000", "vertex3f -0.145351 -0.500000 0.000000", "vertex3f -0.145351 0.500000 0.000000", "vertex3f -0.295541 0.500000 0.000000", "vertex3f -0.295541 -0.500000 0.000000", "vertex3f -0.245541 -0.500000 0.000000", "vertex3f -0.245541 0.500000 0.000000", "vertex3f -0.389943 0.500000 0.000000", "vertex3f -0.389943 -0.500000 0.000000", "vertex3f -0.339943 -0.500000 0.000000", "vertex3f -0.339943 0.500000 0.000000", "vertex3f 0.145351 0.500000 0.000000", "vertex3f 0.145351 -0.500000 0.000000", "vertex3f 0.195351 -0.500000 0.000000", "vertex3f 0.195351 0.500000 0.000000", "vertex3f 0.245541 0.500000 0.000000", "vertex3f 0.245541 -0.500000 0.000000", "vertex3f 0.295541 -0.500000 0.000000", "vertex3f 0.295541 0.500000 0.000000", "vertex3f 0.339943 0.500000 0.000000", "vertex3f 0.339943 -0.500000 0.000000", "vertex3f 0.389943 -0.500000 0.000000", "vertex3f 0.389943 0.500000 0.000000", "end_quads", NULL }; searchandrescue_1.7.0/sar/runway/runway_midway_markers.x3d0000664000175000001440000000106612046776420023162 0ustar jesseusersstatic char *runway_midway_markers_x3d[] = { "X3D Model File", "", "camera 5.000000 5.000000 5.000000 -0.577350 -0.577350 -0.577350 0.698132 0.010000 1000000.000000", "", "begin_quads", "normal3f 0.000000 0.000000 1.000000", "vertex3f -0.350000 0.500000 0.000000", "vertex3f -0.350000 -0.500000 0.000000", "vertex3f -0.200000 -0.500000 0.000000", "vertex3f -0.200000 0.500000 0.000000", "vertex3f 0.200000 0.500000 0.000000", "vertex3f 0.200000 -0.500000 0.000000", "vertex3f 0.350000 -0.500000 0.000000", "vertex3f 0.350000 0.500000 0.000000", "end_quads", NULL }; searchandrescue_1.7.0/sar/runway/runway_displaced_threshold.x3d0000664000175000001440000000332212046776421024146 0ustar jesseusersstatic char *runway_displaced_threshold_x3d[] = { "X3D Model File", "", "camera 5.000000 5.000000 5.000000 -0.577350 -0.577350 -0.577350 0.698132 0.010000 1000000.000000", "", "begin_quads", "normal3f 0.000000 0.000000 1.000000", "vertex3f 0.500000 0.985000 0.000000", "vertex3f 0.500000 1.000000 0.000000", "vertex3f -0.500000 1.000000 0.000000", "vertex3f -0.500000 0.985000 0.000000", "end_quads", "begin_triangles", "vertex3f -0.300000 0.940000 0.000000", "vertex3f -0.400000 0.985000 0.000000", "vertex3f -0.500000 0.940000 0.000000", "vertex3f -0.100000 0.940000 0.000000", "vertex3f -0.200000 0.985000 0.000000", "vertex3f -0.300000 0.940000 0.000000", "vertex3f 0.100000 0.940000 0.000000", "vertex3f 0.000000 0.985000 0.000000", "vertex3f -0.100000 0.940000 0.000000", "vertex3f 0.300000 0.940000 0.000000", "vertex3f 0.200000 0.985000 0.000000", "vertex3f 0.100000 0.940000 0.000000", "vertex3f 0.500000 0.940000 0.000000", "vertex3f 0.400000 0.985000 0.000000", "vertex3f 0.300000 0.940000 0.000000", "vertex3f 0.096172 0.697703 0.000000", "vertex3f -0.003828 0.742703 0.000000", "vertex3f -0.103828 0.697703 0.000000", "vertex3f 0.100000 0.534375 0.000000", "vertex3f 0.000000 0.579375 0.000000", "vertex3f -0.100000 0.534375 0.000000", "vertex3f 0.100000 0.819940 0.000000", "vertex3f 0.000000 0.864940 0.000000", "vertex3f -0.100000 0.819940 0.000000", "vertex3f 0.100000 0.400247 0.000000", "vertex3f 0.000000 0.445247 0.000000", "vertex3f -0.100000 0.400247 0.000000", "vertex3f 0.100000 0.233081 0.000000", "vertex3f 0.000000 0.278081 0.000000", "vertex3f -0.100000 0.233081 0.000000", "vertex3f 0.100000 0.100933 0.000000", "vertex3f 0.000000 0.145933 0.000000", "vertex3f -0.100000 0.100933 0.000000", "end_triangles", NULL }; searchandrescue_1.7.0/sar/runway/runway_threshold.x3d0000664000175000001440000000274112046776421022142 0ustar jesseusersstatic char *runway_threshold_x3d[] = { "X3D Model File", "", "camera 2.974154 -1.015350 2.500000 -0.833240 0.325131 -0.447214 0.698132 0.010000 1000000.000000", "", "begin_quads", "normal3f 0.000000 0.000000 1.000000", "vertex3f -0.350000 0.000000 0.000000", "vertex3f -0.350000 1.000000 0.000000", "vertex3f -0.400000 1.000000 0.000000", "vertex3f -0.400000 0.000000 0.000000", "vertex3f -0.250000 0.000000 0.000000", "vertex3f -0.250000 1.000000 0.000000", "vertex3f -0.300000 1.000000 0.000000", "vertex3f -0.300000 0.000000 0.000000", "vertex3f -0.150000 0.000000 0.000000", "vertex3f -0.150000 1.000000 0.000000", "vertex3f -0.200000 1.000000 0.000000", "vertex3f -0.200000 0.000000 0.000000", "vertex3f -0.050000 0.000000 0.000000", "vertex3f -0.050000 1.000000 0.000000", "vertex3f -0.100000 1.000000 0.000000", "vertex3f -0.100000 0.000000 0.000000", "vertex3f 0.400000 0.000000 0.000000", "vertex3f 0.400000 1.000000 0.000000", "vertex3f 0.350000 1.000000 0.000000", "vertex3f 0.350000 0.000000 0.000000", "vertex3f 0.300000 0.000000 0.000000", "vertex3f 0.300000 1.000000 0.000000", "vertex3f 0.250000 1.000000 0.000000", "vertex3f 0.250000 0.000000 0.000000", "vertex3f 0.200000 0.000000 0.000000", "vertex3f 0.200000 1.000000 0.000000", "vertex3f 0.150000 1.000000 0.000000", "vertex3f 0.150000 0.000000 0.000000", "vertex3f 0.100000 0.000000 0.000000", "vertex3f 0.100000 1.000000 0.000000", "vertex3f 0.050000 1.000000 0.000000", "vertex3f 0.050000 0.000000 0.000000", "end_quads", NULL }; searchandrescue_1.7.0/sar/x3d.c0000664000175000001440000003424512046776377015454 0ustar jesseusers#include #include #include #ifdef __MSW__ # include #endif #include #include "../include/string.h" #include "x3d.h" static const char *X3DGetValues1f(const char *arg, GLfloat *vf); static const char *X3DGetValues2f(const char *arg, GLfloat *vf); static const char *X3DGetValues3f(const char *arg, GLfloat *vf); static const char *X3DGetValues4f(const char *arg, GLfloat *vf); static GLuint X3DMatchTexture( X3DTextureRef **texture, int total_textures, const char *name ); GLuint X3DOpenDataGLList( char **data, const X3DInterpValues *v, X3DTextureRef **texture, int total_textures ); void X3DOpenDataGLOutput( char **data, const X3DInterpValues *v, X3DTextureRef **texture, int total_textures ); X3DTextureRef *X3DTextureRefAppend( X3DTextureRef ***texture, int *total_textures, const char *name, GLuint id ); void X3DTextureDeleteAll( X3DTextureRef ***texture, int *total_textures ); #define ISBLANK(c) (((c) == ' ') || ((c) == '\t')) #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? (float)atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) /* * Get 1 value from the argument string arg and seek arg to the * 2nd argument (or returns NULL if end of string is reached). */ static const char *X3DGetValues1f(const char *arg, GLfloat *vf) { if((arg != NULL) ? (*arg == '\0') : GL_TRUE) { vf[0] = 0.0f; return(NULL); } /* Seek to 1st argument and get argument. */ while(ISBLANK(*arg)) arg++; vf[0] = ATOF(arg); /* Seek to 2nd argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; /* Return new argument position or NULL if end of string. */ return((*arg != '\0') ? arg : NULL); } /* * Get 2 values from the argument string arg and seek arg to the * 3rd argument (or returns NULL if end of string is reached). */ static const char *X3DGetValues2f(const char *arg, GLfloat *vf) { if((arg != NULL) ? (*arg == '\0') : GL_TRUE) { vf[0] = 0.0f; vf[1] = 0.0f; return(NULL); } /* Seek to 1st argument and get argument. */ while(ISBLANK(*arg)) arg++; vf[0] = ATOF(arg); /* Seek to 2nd argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[1] = ATOF(arg); /* Seek to 3rd argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; /* Return new argument position or NULL if end of string. */ return((*arg != '\0') ? arg : NULL); } /* * Get 3 values from the argument string arg and seek arg to the * 4th argument (or returns NULL if end of string is reached). */ static const char *X3DGetValues3f(const char *arg, GLfloat *vf) { if((arg != NULL) ? (*arg == '\0') : GL_TRUE) { vf[0] = 0.0f; vf[1] = 0.0f; vf[2] = 0.0f; return(NULL); } /* Seek to 1st argument and get argument. */ while(ISBLANK(*arg)) arg++; vf[0] = ATOF(arg); /* Seek to 2nd argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[1] = ATOF(arg); /* Seek to 3rd argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[2] = ATOF(arg); /* Seek to 4th argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; /* Return new argument position or NULL if end of string. */ return((*arg != '\0') ? arg : NULL); } /* * Get 4 values from the argument string arg and seek arg to the * 5th argument (or returns NULL if end of string is reached). */ static const char *X3DGetValues4f(const char *arg, GLfloat *vf) { if((arg != NULL) ? (*arg == '\0') : GL_TRUE) { vf[0] = 0.0f; vf[1] = 0.0f; vf[2] = 0.0f; vf[3] = 0.0f; return(NULL); } /* Seek to 1st argument and get argument. */ while(ISBLANK(*arg)) arg++; vf[0] = ATOF(arg); /* Seek to 2nd argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[1] = ATOF(arg); /* Seek to 3rd argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[2] = ATOF(arg); /* Seek to 4th argument and get argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; vf[3] = ATOF(arg); /* Seek to 5th argument. */ while(!ISBLANK(*arg) && (*arg != '\0')) arg++; while(ISBLANK(*arg)) arg++; /* Return new argument position or NULL if end of string. */ return((*arg != '\0') ? arg : NULL); } /* * Returns a gl texture id that matches the given texture name in * the list or returns 0 on failed match. */ static GLuint X3DMatchTexture( X3DTextureRef **texture, int total_textures, const char *name ) { int i; X3DTextureRef *t; if(name == NULL) return(0); for(i = 0; i < total_textures; i++) { t = texture[i]; if(t == NULL) continue; if(t->name == NULL) continue; if(!strcasecmp(t->name, name)) return(t->id); } return(0); } /* * Open the X3D data into a GL list. */ GLuint X3DOpenDataGLList( char **data, const X3DInterpValues *v, X3DTextureRef **texture, int total_textures ) { GLuint gllist = glGenLists(1); glNewList(gllist, GL_COMPILE); X3DOpenDataGLOutput(data, v, texture, total_textures); glEndList(); return(gllist); } /* * Open the X3D data and send it out as GL commands. */ void X3DOpenDataGLOutput( char **data, const X3DInterpValues *v, X3DTextureRef **texture, int total_textures ) { GLboolean texture_on = GL_FALSE; unsigned long flags = X3D_DEFAULT_VALUE_FLAGS; int coordinate_system = X3D_COORDINATE_SYSTEM_XYZ; GLfloat scale_x = 1.0f, scale_y = 1.0f, scale_z = 1.0f; GLfloat offset_x = 0.0f, offset_y = 0.0f, offset_z = 0.0f; int i; char *s, *s2, *s_end; const char *arg; char parm[X3D_PARM_MAX]; if(data == NULL) return; /* Get interpretation values. */ if(v != NULL) { flags = v->flags; if(flags & X3D_VALUE_FLAG_COORDINATE_SYSTEM) coordinate_system = v->coordinate_system; if(flags & X3D_VALUE_FLAG_SCALE) { scale_x = v->scale_x; scale_y = v->scale_y; scale_z = v->scale_z; } if(flags & X3D_VALUE_FLAG_OFFSET) { offset_x = v->offset_x; offset_y = v->offset_y; offset_z = v->offset_z; } } /* Iterate through each data line. */ for(i = 0; data[i] != NULL; i++) { /* Skip to line #4 (lines #0 to #3 are header and ignored). */ if(i < 4) continue; /* Get parameter. */ s = data[i]; s_end = s + X3D_PARM_MAX - 1; s2 = parm; while(!ISBLANK(*s) && (*s != '\0') && (s < s_end)) *s2++ = *s++; *s2 = '\0'; /* Get argument. */ arg = s; while(ISBLANK(*arg)) arg++; /* Enable. */ if(!strcasecmp(parm, "enable")) { if(!(flags & X3D_VALUE_FLAG_SKIP_STATE_CHANGES)) { } } /* Disable. */ else if(!strcasecmp(parm, "disable")) { if(!(flags & X3D_VALUE_FLAG_SKIP_STATE_CHANGES)) { } } /* Points. */ else if(!strcasecmp(parm, "begin_points")) { glBegin(GL_POINTS); } else if(!strcasecmp(parm, "end_points")) { glEnd(); } /* Lines. */ else if(!strcasecmp(parm, "begin_lines")) { glBegin(GL_LINES); } else if(!strcasecmp(parm, "end_lines")) { glEnd(); } /* Line strip. */ else if(!strcasecmp(parm, "begin_line_strip")) { glBegin(GL_LINE_STRIP); } else if(!strcasecmp(parm, "end_line_strip")) { glEnd(); } /* Line loop. */ if(!strcasecmp(parm, "begin_line_loop")) { glBegin(GL_LINE_LOOP); } else if(!strcasecmp(parm, "end_line_loop")) { glEnd(); } /* Triangles. */ else if(!strcasecmp(parm, "begin_triangles")) { glBegin(GL_TRIANGLES); } else if(!strcasecmp(parm, "end_triangles")) { glEnd(); } /* Triangle strip. */ else if(!strcasecmp(parm, "begin_triangle_strip")) { glBegin(GL_TRIANGLE_STRIP); } else if(!strcasecmp(parm, "end_triangle_strip")) { glEnd(); } /* Triangle fan. */ else if(!strcasecmp(parm, "begin_triangle_fan")) { glBegin(GL_TRIANGLE_FAN); } else if(!strcasecmp(parm, "end_triangle_fan")) { glEnd(); } /* Quads. */ else if(!strcasecmp(parm, "begin_quads")) { glBegin(GL_QUADS); } else if(!strcasecmp(parm, "end_quads")) { glEnd(); } /* Quad strip. */ else if(!strcasecmp(parm, "begin_quad_strip")) { glBegin(GL_QUAD_STRIP); } else if(!strcasecmp(parm, "end_quad_strip")) { glEnd(); } /* Polygon. */ else if(!strcasecmp(parm, "begin_polygon")) { glBegin(GL_POLYGON); } else if(!strcasecmp(parm, "end_polygon")) { glEnd(); } /* Normal. */ else if(!strcasecmp(parm, "normal") || !strcasecmp(parm, "normal3") || !strcasecmp(parm, "normal3f") ) { GLfloat vf[3]; arg = X3DGetValues3f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_NORMALS)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glNormal3f(vf[0], vf[1], vf[2]); else glNormal3f(vf[0], vf[2], -vf[1]); } } /* Texcoord. */ else if(!strcasecmp(parm, "texcoord1f") || !strcasecmp(parm, "texcoord1") ) { GLfloat vf[1]; arg = X3DGetValues1f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_TEXCOORDS)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glTexCoord1f(vf[0]); else glTexCoord1f(vf[0]); } } else if(!strcasecmp(parm, "texcoord2f") || !strcasecmp(parm, "texcoord2") || !strcasecmp(parm, "texcoord") ) { GLfloat vf[2]; arg = X3DGetValues2f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_TEXCOORDS)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glTexCoord2f(vf[0], vf[1]); else glTexCoord2f(vf[0], 1.0f - vf[1]); } } else if(!strcasecmp(parm, "texcoord3f") || !strcasecmp(parm, "texcoord3") ) { GLfloat vf[3]; arg = X3DGetValues3f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_TEXCOORDS)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glTexCoord3f(vf[0], vf[1], vf[2]); else glTexCoord3f(vf[0], 1.0f - vf[1], vf[2]); } } /* Vertex. */ else if(!strcasecmp(parm, "vertex3f") || !strcasecmp(parm, "vertex3") || !strcasecmp(parm, "vertex") ) { GLfloat vf[3]; arg = X3DGetValues3f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_VERTICES)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glVertex3f( (vf[0] * scale_x) + offset_x, (vf[1] * scale_y) + offset_y, (vf[2] * scale_z) + offset_z ); else glVertex3f( (vf[0] * scale_x) + offset_x, (vf[2] * scale_z) + offset_z, -((vf[1] * scale_y) + offset_y) ); } } else if(!strcasecmp(parm, "vertex4f") || !strcasecmp(parm, "vertex4") ) { GLfloat vf[4]; arg = X3DGetValues4f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_VERTICES)) { if(coordinate_system == X3D_COORDINATE_SYSTEM_GL) glVertex4f( (vf[0] * scale_x) + offset_x, (vf[1] * scale_y) + offset_y, (vf[2] * scale_z) + offset_z, vf[3] ); else glVertex4f( (vf[0] * scale_x) + offset_x, (vf[2] * scale_z) + offset_z, -((vf[1] * scale_y) + offset_y), vf[3] ); } } /* Color */ else if(!strcasecmp(parm, "color3f") || !strcasecmp(parm, "color3") || !strcasecmp(parm, "color") ) { GLfloat vf[3]; arg = X3DGetValues3f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_COLORS)) glColor3f(vf[0], vf[1], vf[2]); } else if(!strcasecmp(parm, "color4f") || !strcasecmp(parm, "color4") ) { GLfloat vf[4]; arg = X3DGetValues4f(arg, vf); if(!(flags & X3D_VALUE_FLAG_SKIP_COLORS)) glColor4f(vf[0], vf[1], vf[2], vf[3]); } /* Bind Texture */ else if(!strcasecmp(parm, "bind_texture_1d")) { GLuint id = X3DMatchTexture(texture, total_textures, arg); if(id != 0) { glBindTexture(GL_TEXTURE_1D, id); texture_on = GL_TRUE; } else { glBindTexture(GL_TEXTURE_1D, 0); texture_on = GL_FALSE; } } else if(!strcasecmp(parm, "bind_texture_2d") || !strcasecmp(parm, "bind_texture") ) { GLuint id = X3DMatchTexture(texture, total_textures, arg); if(id != 0) { glBindTexture(GL_TEXTURE_2D, id); texture_on = GL_TRUE; } else { glBindTexture(GL_TEXTURE_2D, 0); texture_on = GL_FALSE; } } #ifdef GL_TEXTURE_3D else if(!strcasecmp(parm, "bind_texture_3d")) { GLuint id = X3DMatchTexture(texture, total_textures, arg); if(id != 0) { glBindTexture(GL_TEXTURE_3D, id); texture_on = GL_TRUE; } else { glBindTexture(GL_TEXTURE_3D, 0); texture_on = GL_FALSE; } } #endif } } /* * Appends a texture reference to the list. */ X3DTextureRef *X3DTextureRefAppend( X3DTextureRef ***texture, int *total_textures, const char *name, GLuint id ) { int i; X3DTextureRef *t = NULL; if((texture == NULL) || (total_textures == NULL)) return(t); i = MAX(*total_textures, 0); *total_textures = i + 1; *texture = (X3DTextureRef **)realloc( *texture, (*total_textures) * sizeof(X3DTextureRef *) ); if(*texture == NULL) { *total_textures = 0; return(t); } *texture[i] = t = (X3DTextureRef *)calloc( 1, sizeof(X3DTextureRef) ); if(t == NULL) return(t); t->name = STRDUP(name); t->id = id; return(t); } /* * Delete all texture references. */ void X3DTextureDeleteAll( X3DTextureRef ***texture, int *total_textures ) { int i; X3DTextureRef *t; if((texture == NULL) || (total_textures == NULL)) return; for(i = 0; i < *total_textures; i++) { t = (*texture)[i]; if(t == NULL) continue; free(t->name); free(t); } free(*texture); *texture = NULL; *total_textures = 0; } searchandrescue_1.7.0/sar/platforms.ini0000664000175000001440000004664612046776377017332 0ustar jesseusers# Platforms configuration file for Platform Configurator. # # See FORMAT for specifications about this file. # MakefileOutput = sar/Makefile MakefileInputPrepend = sar/makefile_prepend.ini MakefileInputAppend = sar/makefile_append.ini ThisPlatformInfo = sar/this_platform.ini MessageConfigStartup = Checking this platform... MessagePlatformUnsupported = Sorry, that platform is not supported, \ please try a different or generic platform if available. Use --listall \ to obtain a complete list of platforms. MessageDependFailed = One or more compoents are not available on your \ system, please install them first and then resume this configuration. MessageSuccess = Type 'make all' to begin compiling this program. # # Platforms section: # Platform = UNIX Description = For most any UNIX system PREFIX = /usr/ CFLAGS = -Wall -O2 -funroll-loops -fomit-frame-pointer \ -ffast-math -D__USE_BSD -DHAVE_SDL_MIXER -Wno-write-strings LIBS = -lm -lSDL -lSDL_mixer LIB_DIR = CC = cc CPP = c++ PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/X11R6/include/ PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathLib = /usr/X11R6/lib/ PlatformSearchPathEtc = /etc/ PlatformSearchPathEtc = /usr/etc/ PlatformSearchPathBin = /bin/ PlatformSearchPathBin = /usr/bin/ PlatformSearchPathBin = /usr/X11R6/bin/ PlatformSearchPathBin = /usr/games/ PlatformSearchPathData = /usr/share/icons/ PlatformSearchPathData = /usr/share/games/ PlatformFeature = debug Description = Just adds -g to the CFLAGS for debugging MustExist = No FeatureCFLAGS = -g # PlatformFeature = libjsw # Description = For joystick support # MustExist = Preferred # FeatureCFLAGS = -DJS_SUPPORT # FeatureLIBS = -ljsw # FeatureDepend = jsw-lib # DependType = Library # MustExist = Yes # DependPath = libjsw.so # DependGrepString = JSInit # FeatureDepend = jsw-devel # DependType = Header # MustExist = Yes # DependPath = jsw.h # DependGrepString = JSInit PlatformFeature = X11 Description = X Window Systems MustExist = Yes FeatureCFLAGS = -DUSE_XSHM -DHAVE_MWMUTIL_H FeatureLIBS = -lSM -lICE -lX11 -lXext -lXmu FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = X11-lib DependType = Library MustExist = Yes DependPath = libX11.so DependGrepString = XOpenDisplay FeatureDepend = X11-devel DependType = Header MustExist = Yes DependPath = X11/Xlib.h DependGrepString = XOpenDisplay PlatformFeature = libXpm Description = XPM image IO library MustExist = Yes FeatureCFLAGS = -DHAVE_LIBXPM FeatureLIBS = -lXpm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xpm-lib DependType = Library MustExist = Yes DependPath = libXpm.so DependGrepString = XpmCreatePixmapFromData FeatureDepend = xpm-devel DependType = Header MustExist = Yes DependPath = X11/xpm.h DependGrepString = XpmCreatePixmapFromData PlatformFeature = XF86VidMode Description = XF86 Video Mode extension MustExist = Preferred FeatureCFLAGS = -DHAVE_XF86_VIDMODE FeatureLIBS = -lXxf86vm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xf86vidmode-lib DependType = Library MustExist = Yes DependPath = libXxf86vm.a DependGrepString = XF86VidModeQueryExtension FeatureDepend = xf86vidmode-devel DependType = Header MustExist = Yes DependPath = X11/extensions/xf86vmode.h DependGrepString = XF86VidModeQueryExtension PlatformFeature = opengl Description = An implementation of OpenGL (ie Mesa3D) MustExist = Yes FeatureLIBS = -lGL -lGLU FeatureDepend = gl-lib DependType = Library MustExist = Yes DependPath = libGL.so DependGrepString = glEnable DependPath = libGLU.so DependGrepString = gluPerspective FeatureDepend = gl-devel DependType = Header MustExist = Yes DependPath = GL/gl.h DependGrepString = glEnable # We no longer need Y2, it has been replaced with SDL. # PlatformFeature = Y2 # Description = For multi-client sound support # MustExist = Preferred # FeatureCFLAGS = -DHAVE_Y2 # FeatureLIBS = -lY2 # FeatureDepend = Y2-lib # DependType = Library # MustExist = Yes # DependPath = libY2.so # DependGrepString = YOpenConnection # FeatureDepend = Y2-devel # DependType = Header # MustExist = Yes # DependPath = Y2/Ylib.h # DependGrepString = YOpenConnection Platform = Linux Description = For most any Linux system PREFIX = $(DESTDIR)/usr/ CFLAGS = -Wall -O2 -funroll-loops -fomit-frame-pointer \ -ffast-math -finline-functions -D__USE_BSD -DHAVE_SDL_MIXER -Wno-write-strings LIBS = -lm -lSDL -lSDL_mixer LIB_DIR = CC = gcc CPP = g++ PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/X11R6/include/ PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathLib = /usr/lib/alpha-linux-gnu/ PlatformSearchPathLib = /usr/lib/arm-linux-gnueabi/ PlatformSearchPathLib = /usr/lib/arm-linux-gnueabihf/ PlatformSearchPathLib = /usr/lib/avr32-linux-gnu/ PlatformSearchPathLib = /usr/lib/hppa-linux-gnu/ PlatformSearchPathLib = /usr/lib/i386-gnu/ PlatformSearchPathLib = /usr/lib/i386-kfreebsd-gnu/ PlatformSearchPathLib = /usr/lib/i386-linux-gnu/ PlatformSearchPathLib = /usr/lib/ia64-linux-gnu/ PlatformSearchPathLib = /usr/lib/lsb3/ PlatformSearchPathLib = /usr/lib/m68k-linux-gnu/ PlatformSearchPathLib = /usr/lib/mips-linux-gnu/ PlatformSearchPathLib = /usr/lib/mipsel-linux-gnu/ PlatformSearchPathLib = /usr/lib/powerpc-linux-gnu/ PlatformSearchPathLib = /usr/lib/powerpc-linux-gnuspe/ PlatformSearchPathLib = /usr/lib/s390-linux-gnu/ PlatformSearchPathLib = /usr/lib/s390x-linux-gnu/ PlatformSearchPathLib = /usr/lib/sh4-linux-gnu/ PlatformSearchPathLib = /usr/lib/sparc-linux-gnu/ PlatformSearchPathLib = /usr/lib/sparc64-linux-gnu/ PlatformSearchPathLib = /usr/lib/x86_64-kfreebsd-gnu/ PlatformSearchPathLib = /usr/lib/x86_64-linux-gnu/ PlatformSearchPathLib = /usr/lib32/ PlatformSearchPathLib = /usr/X11R6/lib/ PlatformSearchPathEtc = /etc/ PlatformSearchPathEtc = /usr/etc/ PlatformSearchPathBin = /bin/ PlatformSearchPathBin = /usr/bin/ PlatformSearchPathBin = /usr/X11R6/bin/ PlatformSearchPathBin = /usr/games/ PlatformSearchPathData = /usr/share/icons/ PlatformSearchPathData = /usr/share/games/ PlatformFeature = debug Description = Just adds -g to the CFLAGS for debugging MustExist = No FeatureCFLAGS = -g # PlatformFeature = libjsw # Description = For joystick support # MustExist = Preferred # FeatureCFLAGS = -DJS_SUPPORT # FeatureLIBS = -ljsw # FeatureDepend = jsw-lib # DependType = Library # MustExist = Yes # DependPath = libjsw.so # DependGrepString = JSInit # FeatureDepend = jsw-devel # DependType = Header # MustExist = Yes # DependPath = jsw.h # DependGrepString = JSInit PlatformFeature = X11 Description = X Window Systems MustExist = Yes FeatureCFLAGS = -DUSE_XSHM -DHAVE_MWMUTIL_H FeatureLIBS = -lSM -lICE -lX11 -lXext -lXmu FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = X11-lib DependType = Library MustExist = Yes DependPath = libX11.so DependGrepString = XOpenDisplay FeatureDepend = X11-devel DependType = Header MustExist = Yes DependPath = X11/Xlib.h DependGrepString = XOpenDisplay PlatformFeature = libXpm Description = XPM image IO library MustExist = Yes FeatureCFLAGS = -DHAVE_LIBXPM FeatureLIBS = -lXpm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xpm-lib DependType = Library MustExist = Yes DependPath = libXpm.so DependGrepString = XpmCreatePixmapFromData FeatureDepend = xpm-devel DependType = Header MustExist = Yes DependPath = X11/xpm.h DependGrepString = XpmCreatePixmapFromData PlatformFeature = XF86VidMode Description = XF86 Video Mode extension MustExist = Preferred FeatureCFLAGS = -DHAVE_XF86_VIDMODE FeatureLIBS = -lXxf86vm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xf86vidmode-lib DependType = Library MustExist = Yes DependPath = libXxf86vm.a DependGrepString = XF86VidModeQueryExtension FeatureDepend = xf86vidmode-devel DependType = Header MustExist = Yes DependPath = X11/extensions/xf86vmode.h DependGrepString = XF86VidModeQueryExtension PlatformFeature = opengl Description = An implementation of OpenGL (ie Mesa3D) MustExist = Yes # On Linux there is a ld.so bug where not linking to pthread for OpenGL # causes some problems. So if we want OpenGL we need to also link to # libpthread. FeatureLIBS = -lGL -lGLU -lpthread FeatureDepend = gl-lib DependType = Library MustExist = Yes DependPath = libGL.so DependGrepString = glEnable DependPath = libGLU.so DependGrepString = gluPerspective FeatureDepend = gl-devel DependType = Header MustExist = Yes DependPath = GL/gl.h DependGrepString = glEnable # Y2 has been replaced with SDL. # PlatformFeature = Y2 # Description = For multi-client sound support # MustExist = Preferred # FeatureCFLAGS = -DHAVE_Y2 # FeatureLIBS = -lY2 # FeatureDepend = Y2-lib # DependType = Library # MustExist = Yes # DependPath = libY2.so # DependGrepString = YOpenConnection # FeatureDepend = Y2-devel # DependType = Header # MustExist = Yes # DependPath = Y2/Ylib.h # DependGrepString = YOpenConnection Platform = BSD Description = For most any BSD system PREFIX = $(DESTDIR)/usr/ CFLAGS = -Wall -O2 -funroll-loops -fomit-frame-pointer \ -ffast-math -finline-functions -D__USE_BSD -DHAVE_SDL_MIXER -Wno-write-strings LIBS = -lm -lSDL -lSDL_mixer LIB_DIR = CC = clang CPP = clang++ PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/X11R6/include/ PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathLib = /usr/lib/alpha-linux-gnu/ PlatformSearchPathLib = /usr/lib/arm-linux-gnueabi/ PlatformSearchPathLib = /usr/lib/arm-linux-gnueabihf/ PlatformSearchPathLib = /usr/lib/avr32-linux-gnu/ PlatformSearchPathLib = /usr/lib/hppa-linux-gnu/ PlatformSearchPathLib = /usr/lib/i386-gnu/ PlatformSearchPathLib = /usr/lib/i386-kfreebsd-gnu/ PlatformSearchPathLib = /usr/lib/i386-linux-gnu/ PlatformSearchPathLib = /usr/lib/ia64-linux-gnu/ PlatformSearchPathLib = /usr/lib/lsb3/ PlatformSearchPathLib = /usr/lib/m68k-linux-gnu/ PlatformSearchPathLib = /usr/lib/mips-linux-gnu/ PlatformSearchPathLib = /usr/lib/mipsel-linux-gnu/ PlatformSearchPathLib = /usr/lib/powerpc-linux-gnu/ PlatformSearchPathLib = /usr/lib/powerpc-linux-gnuspe/ PlatformSearchPathLib = /usr/lib/s390-linux-gnu/ PlatformSearchPathLib = /usr/lib/s390x-linux-gnu/ PlatformSearchPathLib = /usr/lib/sh4-linux-gnu/ PlatformSearchPathLib = /usr/lib/sparc-linux-gnu/ PlatformSearchPathLib = /usr/lib/sparc64-linux-gnu/ PlatformSearchPathLib = /usr/lib/x86_64-kfreebsd-gnu/ PlatformSearchPathLib = /usr/lib/x86_64-linux-gnu/ PlatformSearchPathLib = /usr/lib32/ PlatformSearchPathLib = /usr/X11R6/lib/ PlatformSearchPathEtc = /etc/ PlatformSearchPathEtc = /usr/etc/ PlatformSearchPathBin = /bin/ PlatformSearchPathBin = /usr/bin/ PlatformSearchPathBin = /usr/X11R6/bin/ PlatformSearchPathBin = /usr/games/ PlatformSearchPathData = /usr/share/icons/ PlatformSearchPathData = /usr/share/games/ PlatformFeature = debug Description = Just adds -g to the CFLAGS for debugging MustExist = No FeatureCFLAGS = -g # PlatformFeature = libjsw # Description = For joystick support # MustExist = Preferred # FeatureCFLAGS = -DJS_SUPPORT # FeatureLIBS = -ljsw # FeatureDepend = jsw-lib # DependType = Library # MustExist = Yes # DependPath = libjsw.so # DependGrepString = JSInit # FeatureDepend = jsw-devel # DependType = Header # MustExist = Yes # DependPath = jsw.h # DependGrepString = JSInit PlatformFeature = X11 Description = X Window Systems MustExist = Yes FeatureCFLAGS = -DUSE_XSHM -DHAVE_MWMUTIL_H FeatureLIBS = -lSM -lICE -lX11 -lXext -lXmu FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = X11-lib DependType = Library MustExist = Yes DependPath = libX11.so DependGrepString = XOpenDisplay FeatureDepend = X11-devel DependType = Header MustExist = Yes DependPath = X11/Xlib.h DependGrepString = XOpenDisplay PlatformFeature = libXpm Description = XPM image IO library MustExist = Yes FeatureCFLAGS = -DHAVE_LIBXPM FeatureLIBS = -lXpm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xpm-lib DependType = Library MustExist = Yes DependPath = libXpm.so DependGrepString = XpmCreatePixmapFromData FeatureDepend = xpm-devel DependType = Header MustExist = Yes DependPath = X11/xpm.h DependGrepString = XpmCreatePixmapFromData PlatformFeature = XF86VidMode Description = XF86 Video Mode extension MustExist = Preferred FeatureCFLAGS = -DHAVE_XF86_VIDMODE FeatureLIBS = -lXxf86vm FeatureLIB_DIR = -L/usr/X11R6/lib/ FeatureDepend = xf86vidmode-lib DependType = Library MustExist = Yes DependPath = libXxf86vm.a DependGrepString = XF86VidModeQueryExtension FeatureDepend = xf86vidmode-devel DependType = Header MustExist = Yes DependPath = X11/extensions/xf86vmode.h DependGrepString = XF86VidModeQueryExtension PlatformFeature = opengl Description = An implementation of OpenGL (ie Mesa3D) MustExist = Yes # On Linux there is a ld.so bug where not linking to pthread for OpenGL # causes some problems. So if we want OpenGL we need to also link to # libpthread. FeatureLIBS = -lGL -lGLU -lpthread FeatureDepend = gl-lib DependType = Library MustExist = Yes DependPath = libGL.so DependGrepString = glEnable DependPath = libGLU.so DependGrepString = gluPerspective FeatureDepend = gl-devel DependType = Header MustExist = Yes DependPath = GL/gl.h DependGrepString = glEnable # Y2 has been replaced with SDL. # PlatformFeature = Y2 # Description = For multi-client sound support # MustExist = Preferred # FeatureCFLAGS = -DHAVE_Y2 # FeatureLIBS = -lY2 # FeatureDepend = Y2-lib # DependType = Library # MustExist = Yes # DependPath = libY2.so # DependGrepString = YOpenConnection # FeatureDepend = Y2-devel # DependType = Header # MustExist = Yes # DependPath = Y2/Ylib.h # DependGrepString = YOpenConnection searchandrescue_1.7.0/sar/sarcamp.h0000644000175000001440000000714013452214565016365 0ustar jesseusers/* This header file contains all the function definitions and misc items needed to get a campaign underway. -- Jesse */ #ifndef CAMPAIGN_HEADER_FILE__ #define CAMPAIGN_HEADER_FILE__ #ifndef True #define True 1 #endif #ifndef False #define False 0 #endif #define OBJECTIVE_ARRIVE 0 #define OBJECTIVE_PICKUP 1 #define MAX_OBJECTIVES 5 #define LOCATION_NONE 0 #define LOCATION_LAX 1 #define LOCATION_SMO 2 #define LOCATION_UCLA 3 #define LOCATION_CAT 4 #define LOCATION_USCG 5 #define LOCATION_ENTERPRISE 6 #define LOCATION_SEARCH 7 #define MAX_PLACES 6 #define RESCUE_DISTANCE 5000 /* Create an empty campaign file where we can write to it. Returns an open file on success and NULL on failure. */ FILE *Create_Campaign_File(); /* This function returns a string with one of eight possible weather conditions. The string should be freed after use. On error, NULL is returned. */ char *Create_Campaign_Weather(); /* This function returns a filename for a scenery location. The string should be freed after use. On error, NULL is returned. */ char *Create_Campaign_Scenery(); /* Picks a place to start at random. The function returns a location number. */ int Create_Campaign_Start_Point(); char *Create_Campaign_Description(int first_objective); /* Creates a string that will contains all aspects of an arrival mission. The returned string should be freed after use. The parameters taken in to the function represent where they are currently going and where they will go after reaching their current destination. */ char *Create_Campaign_Arrive_Objective(int current_destination, int next_destination); char *Create_Campaign_Pickup_Objective(int next_location); /* This function returns a string which contains a location internal name. For example, helipad_lax or helipad_cat. The string should be freed after use. */ char *Get_Location_Symbol(int location); /* This function returns a location's proper name, at it appears to the player. The returned string should be freed after use. */ char *Get_Location_Name(int location); /* Accepts a location and returns the map coordinates for that location. The function returns True if it knows the location and False if it is an unknown place. */ int Get_Coordinates(int location, int *x, int *y); /* This function returns a string which gives the location of the USCG ship and its helipad. If an error occurs, then NULL is returned. The returned string should be freed after use. */ // char *Place_Campaign_Ship(); /* This function returns a long string which contains all the location data for humans who need to be picked up. The function takes in a list of destinations and the pilot's start point. It then tries to place humans near where the pilot will be. On success, a string is returned which can be written to the mission file. The string should be freed after use. On error, NULL is returned. */ char *Place_Campaign_Humans(int start_location, int *destinations); /* This function selects an appropriate craft for the mission. A string with the craft name is returned. If an error occures, NULL is returned. The string should be freed after use. */ char *Create_Campaign_Aircraft(int all_arrivals); /* Creates a filename, though not a file, which should be created in the user's home directory. On success, a string is returned, which should be freed after use. On failure, NULL is returned. */ char *Get_Campaign_Filename(); /* This function is the wrapper for all the above functions. It creates a new mission file, fills it with missiony goodness and closes the file. On success it returns True and on error it returns False and prints a message to standard out. */ int Create_Campaign(); #endif searchandrescue_1.7.0/sar/this_platform.ini0000664000175000001440000000003512046776416020146 0ustar jesseusersLinux 2.6.31-14-generic i686 searchandrescue_1.7.0/sar/sceneio.c0000664000175000001440000012143512046776416016373 0ustar jesseusers#include #include #include #include #include #include #include #ifdef __MSW__ # include #endif #include #include "../include/fio.h" #include "../include/string.h" #include "../include/strexp.h" #include "../include/disk.h" #include "gw.h" #include "cp.h" #include "sfm.h" #include "sarreality.h" #include "obj.h" #include "objsound.h" #include "objutils.h" #include "objio.h" #include "messages.h" #include "simmanage.h" #include "simcb.h" #include "simutils.h" #include "weather.h" #include "sar.h" #include "sarfio.h" #include "sceneio.h" #include "config.h" void SARSceneDestroy( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total ); void SARSceneLoadLocationsToList( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_list_struct *list, int list_num, const char *filename ); int SARSceneAddPlayerObject( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *model_file, sar_position_struct *pos, sar_direction_struct *dir ); int SARSceneLoadFromFile( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *filename, const char *weather_preset_name, void *client_data, int (*progress_func)(void *, long, long) ); #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define RADTODEG(r) ((r) * 180 / PI) #define DEGTORAD(d) ((d) * PI / 180) #define ISCOMMENT(c) ((c) == SAR_COMMENT_CHAR) #define ISCR(c) (((c) == '\n') || ((c) == '\r')) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) /* * Deletes all resources on the scene structure and all * objects on the given objects pointer array. * * Does not delete the scene structure itself, but the * scene structure will be reset. */ void SARSceneDestroy( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total ) { int i; const sar_option_struct *opt = &core_ptr->option; if(opt->runtime_debug) printf("SARSceneDestroy(): Destroying scene...\n"); /* Check if total objects is not NULL (which implies ptr is not * NULL) */ if(total != NULL) { /* Delete objects pointer array from last to first */ for(i = (*total) - 1; i >= 0; i--) SARObjDelete(core_ptr, ptr, total, i); *total = 0; } if(ptr != NULL) { free(*ptr); *ptr = NULL; } /* Delete scene */ if(scene != NULL) { sar_scene_base_struct *base = &scene->base; sar_scene_horizon_struct *horizon_ptr = &scene->horizon; /* Title */ free(scene->title); scene->title = NULL; /* Ground base */ /* Visual model simple (far away) */ SARVisualModelUnref(scene, base->visual_model_simple); base->visual_model_simple = NULL; /* Visual model complex (close up) */ SARVisualModelUnref(scene, base->visual_model_close); base->visual_model_close = NULL; /* Cloud Layers */ for(i = 0; i < scene->total_cloud_layers; i++) SARCloudLayerDelete(scene, scene->cloud_layer[i]); free(scene->cloud_layer); scene->cloud_layer = NULL; scene->total_cloud_layers = 0; /* Cloud BillBoards */ for(i = 0; i < scene->total_cloud_bbs; i++) SARCloudBBDelete(scene->cloud_bb[i]); free(scene->cloud_bb); scene->cloud_bb = NULL; scene->total_cloud_bbs = 0; /* Horizon */ horizon_ptr = &scene->horizon; for(i = 0; i < horizon_ptr->total_textures; i++) V3DTextureDestroy(horizon_ptr->texture[i]); free(horizon_ptr->texture); horizon_ptr->texture = NULL; horizon_ptr->total_textures = 0; /* Ground objects list, delete only the pointer array and * not each object */ free(scene->ground_object); scene->ground_object = NULL; scene->total_ground_objects = 0; /* Humans that need rescue list */ free(scene->human_need_rescue_object); scene->human_need_rescue_object = NULL; scene->total_human_need_rescue_objects = 0; /* Visual models, all visual models should have been * unref'ed by now. So here we actually delete * and destroy the GL lists */ SARVisualModelDeleteAll(scene); /* Delete all textures */ for(i = 0; i < scene->total_texture_refs; i++) V3DTextureDestroy(scene->texture_ref[i]); free(scene->texture_ref); /* Free pointer array */ scene->texture_ref = NULL; scene->total_texture_refs = 0; /* Reset texture reference indices for special textures */ scene->texnum_sun = -1; scene->texnum_moon = -1; scene->texnum_spotlightcast = -1; /* Delete all sound sources */ for(i = 0; i < scene->total_sndsrcs; i++) SARSoundSourceDelete(scene->sndsrc[i]); free(scene->sndsrc); scene->sndsrc = NULL; scene->total_sndsrcs = 0; /* Control panel */ CPDelete( (ControlPanel *)scene->player_control_panel ); scene->player_control_panel = NULL; /* Messages */ strlistfree(scene->message, scene->total_messages); scene->message = NULL; scene->total_messages = 0; /* Sticky banner message */ strlistfree( scene->sticky_banner_message, scene->total_sticky_banner_messages ); scene->sticky_banner_message = NULL; scene->total_sticky_banner_messages = 0; /* Camera reference name/description title string */ free(scene->camera_ref_title); scene->camera_ref_title = NULL; /* FDM Realm */ if(scene->realm != NULL) SFMShutdown(scene->realm); /* Reset the rest of the scene structure */ memset(scene, 0x00, sizeof(sar_scene_struct)); } if(opt->runtime_debug) printf("SARSceneDestroy(): Scene destroyed.\n"); } /* * Loads the list of Registered Locations from the specified * scene file to the specified List. */ void SARSceneLoadLocationsToList( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_list_struct *list, int list_num, const char *filename ) { int i, ptype, total_parms; void *p, **parm; if(list == NULL) return; /* Delete existing items in the List */ for(i = 0; i < list->total_items; i++) SARDeleteListItemData(list->item[i]); SARMenuListDeleteAllItems(m, list_num); /* Load all SAR_PARM_REGISTER_LOCATION parameters from the * scene file */ if(SARParmLoadFromFile( filename, SAR_FILE_FORMAT_SCENE, &parm, &total_parms, SAR_PARM_REGISTER_LOCATION, /* Filter */ NULL, NULL )) return; /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; ptype = *(int *)p; if(ptype == SAR_PARM_REGISTER_LOCATION) { int n; sar_menu_list_item_data_struct *d; sar_parm_register_location_struct *pv = (sar_parm_register_location_struct *)p; /* Allocate a new list item data */ d = SAR_MENU_LIST_ITEM_DATA(calloc( 1, sizeof(sar_menu_list_item_data_struct) )); if(d != NULL) { /* Position */ memcpy( &d->pos, &pv->pos, sizeof(sar_position_struct) ); /* Direction */ memcpy( &d->dir, &pv->dir, sizeof(sar_direction_struct) ); /* Name */ d->name = STRDUP(pv->name); /* Add this location to the menu's list object */ n = SARMenuListAppendItem( m, list_num, d->name, d, 0 ); if(n < 0) { fprintf( stderr, "Error appending list item for starting location `%s'\n", d->name ); free(d->filename); free(d->name); free(d); } d = NULL; } } } /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); } /* * Adds a player object to the scene using the specified model * file and initial position & direction. * * Updates the player object references on the scene. * * All inputs must be valid (except for pos and dir). * * Returns non-zero on error. */ int SARSceneAddPlayerObject( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *model_file, sar_position_struct *pos, sar_direction_struct *dir ) { int obj_num; sar_object_struct *obj_ptr; sar_object_aircraft_struct *obj_aircraft_ptr; sar_position_struct lpos; sar_direction_struct ldir; if((core_ptr == NULL) || (scene == NULL) || (model_file == NULL)) return(-1); /* Create player object on to scene */ obj_num = SARObjNew( scene, &core_ptr->object, &core_ptr->total_objects, SAR_OBJ_TYPE_AIRCRAFT ); obj_ptr = (obj_num > -1) ? core_ptr->object[obj_num] : NULL; if(obj_ptr == NULL) return(-1); /* Update player object references on scene structure (this * must be done immediately after creating of the player object * so that SARObjLoadFromFile() can tell this is the player * object */ scene->player_obj_num = obj_num; scene->player_obj_ptr = obj_ptr; /* Load player object model file */ SARObjLoadFromFile(core_ptr, obj_num, model_file); /* Set object name to "player", this will override the name * of this object specified in the model file. This needs to * be set so that subsequent configurations can reffer to * this object by the name of "player" in order to match it * (ie in mission files) */ free(obj_ptr->name); obj_ptr->name = STRDUP("player"); /* Set local position structure */ if(pos != NULL) memcpy(&lpos, pos, sizeof(sar_position_struct)); else memset(&lpos, 0x00, sizeof(sar_position_struct)); /* Adjust ground_elevation_msl so that it's at the position of * the player object, this way the player won't suddenly drop * and be destroyed */ obj_ptr->ground_elevation_msl = lpos.z; /* Move player up from ground level so that it does not added into * the scene while embedded in the ground (which may cause a * crash if the given pos is ontop of a building) */ obj_aircraft_ptr = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(obj_aircraft_ptr != NULL) { lpos.z += (float)MAX(obj_aircraft_ptr->belly_height, 0.0); lpos.z += (float)MAX(obj_aircraft_ptr->gear_height, 0.0); } /* Add other object types that need their position modified here */ /* Set local direction structure */ if(dir != NULL) memcpy(&ldir, dir, sizeof(sar_direction_struct)); else memset(&ldir, 0x00, sizeof(sar_direction_struct)); /* Move player object to starting location and attitude */ SARSimWarpObject(scene, obj_ptr, &lpos, &ldir); return(0); } /* * Opens the Scene from the specified file. * * All default values for the Scene will be allocated/created/set * and any existing values will be deleted/reset. * */ int SARSceneLoadFromFile( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *filename, const char *weather_preset_name, void *client_data, int (*progress_func)(void *, long, long) ) { void *p, **parm; int i, status, ptype, total_parms; int obj_num = -1, *total; gw_display_struct *display; sar_direction_struct *dir; sar_color_struct *c; sar_object_struct *obj_ptr = NULL, ***ptr; sar_object_aircraft_struct *obj_aircraft_ptr = NULL; sar_object_ground_struct *obj_ground_ptr = NULL; sar_object_helipad_struct *obj_helipad_ptr = NULL; sar_object_runway_struct *obj_runway_ptr = NULL; sar_object_human_struct *obj_human_ptr = NULL; sar_object_smoke_struct *obj_smoke_ptr = NULL; sar_object_fire_struct *obj_fire_ptr = NULL; sar_scene_horizon_struct *horizon_ptr; struct stat stat_buf; sar_parm_version_struct *p_version; sar_parm_name_struct *p_name; sar_parm_description_struct *p_description; sar_parm_player_model_file_struct *p_player_model_file; sar_parm_weather_struct *p_weather; sar_parm_register_location_struct *p_register_location; sar_parm_scene_gps_struct *p_scene_gps; sar_parm_scene_map_struct *p_scene_map; sar_parm_scene_elevation_struct *p_scene_elevation; sar_parm_scene_cant_struct *p_scene_cant; sar_parm_scene_ground_flags_struct *p_scene_ground_flags; sar_parm_scene_ground_tile_struct *p_scene_ground_tile; sar_parm_texture_base_directory_struct *p_texture_base_directory; sar_parm_texture_load_struct *p_texture_load; sar_parm_new_object_struct *p_new_object; sar_parm_new_helipad_struct *p_new_helipad; sar_parm_new_runway_struct *p_new_runway; sar_parm_new_human_struct *p_new_human; sar_parm_new_smoke_struct *p_new_smoke; sar_parm_new_fire_struct *p_new_fire; sar_parm_new_premodeled_struct *p_new_premodeled; sar_parm_model_file_struct *p_model_file; sar_parm_range_struct *p_range; sar_parm_range_far_struct *p_range_far; sar_parm_translate_struct *p_translate; sar_parm_translate_random_struct *p_translate_random; sar_parm_rotate_struct *p_rotate; sar_parm_no_depth_test_struct *p_no_depth_test; sar_parm_polygon_offset_struct *p_polygon_offset; sar_parm_contact_bounds_spherical_struct *p_contact_bounds_spherical; sar_parm_contact_bounds_cylendrical_struct *p_contact_bounds_cylendrical; sar_parm_contact_bounds_rectangular_struct *p_contact_bounds_rectangular; sar_parm_ground_elevation_struct *p_ground_elevation; sar_parm_object_name_struct *p_object_name; sar_parm_object_map_description_struct *p_object_map_description; sar_parm_fuel_struct *p_fuel; sar_parm_hitpoints_struct *p_hitpoints; sar_parm_engine_state_struct *p_engine_state; sar_parm_passengers_struct *p_passengers; sar_parm_runway_approach_lighting_north_struct *p_runway_applight_n; sar_parm_runway_approach_lighting_south_struct *p_runway_applight_s; sar_parm_human_message_enter_struct *p_human_message_enter; sar_parm_human_reference_struct *p_human_reference; /* Resets object substructure pointers to NULL */ #define DO_RESET_SUBSTRUCTURE_PTRS { \ obj_aircraft_ptr = NULL; \ obj_ground_ptr = NULL; \ obj_helipad_ptr = NULL; \ obj_runway_ptr = NULL; \ obj_human_ptr = NULL; \ obj_smoke_ptr = NULL; \ obj_fire_ptr = NULL; \ } if((core_ptr == NULL) || (scene == NULL) || (filename == NULL)) return(-1); display = core_ptr->display; ptr = &core_ptr->object; total = &core_ptr->total_objects; /* Check if the file exists and get its stats */ if(stat(filename, &stat_buf)) { char *s = STRDUP(strerror(errno)); if(s == NULL) s = STRDUP("no such file"); *s = toupper(*s); fprintf( stderr, "%s: %s.\n", filename, s ); free(s); return(-1); } /* Load all parameters from file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_SCENE, &parm, &total_parms, -1, /* No filter */ NULL, NULL ); if(status) { fprintf( stderr, "%s: Error loading scene.\n", filename ); return(-1); } /* Delete the specified Scene and all its objects */ SARSceneDestroy(core_ptr, scene, ptr, total); /* Reset Scene values */ scene->tod = (12 * 3600); /* Noon */ scene->tod_code = SAR_TOD_CODE_DAY; scene->cant_angle = (float)(0.0 * PI); scene->base_flags = 0; scene->msl_elevation = 0.0f; scene->dms_x_offset = 0; scene->dms_y_offset = 0; scene->planet_radius = SAR_DEF_PLANET_RADIUS; scene->visual_model = NULL; scene->total_visual_models = 0; c = &scene->sky_nominal_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->sky_brighten_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->sky_darken_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->star_low_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->star_high_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->sun_low_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->sun_high_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->moon_low_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; c = &scene->moon_high_color; c->a = 1.0f; c->r = 1.0f; c->g = 1.0f; c->b = 1.0f; scene->moon_visibility_hint = 0; scene->rain_density_coeff = 0.0f; scene->player_obj_num = -1; scene->player_obj_ptr = NULL; scene->player_has_crashed = False; scene->ground_object = NULL; scene->total_ground_objects = 0; scene->human_need_rescue_object = NULL; scene->total_human_need_rescue_objects = 0; scene->camera_ref = SAR_CAMERA_REF_COCKPIT; scene->camera_fovz = (float)SFMDegreesToRadians(40.0); dir = &scene->camera_cockpit_dir; dir->heading = (float)(0.0f * PI); dir->pitch = (float)(0.0f * PI); dir->bank = (float)(0.0f * PI); dir = &scene->camera_spot_dir; dir->heading = (float)(1.25f * PI); dir->pitch = (float)(1.92f * PI); dir->bank = (float)(0.0f * PI); scene->camera_spot_dist = 20.0f; dir = &scene->camera_hoist_dir; dir->heading = (float)(0.75f * PI); dir->pitch = (float)(1.92f * PI); dir->bank = (float)(0.0f * PI); scene->camera_hoist_dist = 20.0f; scene->camera_target = -1; memset( scene->camera_rotmatrix, 0x00, SAR_CAMERA_ROTMATRIX_MAX * (3 * 3) * sizeof(double) ); scene->camera_rotmatrix_count = 0; scene->light_visibility_hint = 0; scene->light_xc = -2.0f; /* Not in camera view */ scene->light_yc = -2.0f; scene->cloud_layer = NULL; scene->total_cloud_layers = 0; scene->cloud_bb = NULL; scene->total_cloud_bbs = 0; scene->pri_lightening_coeff = 0.0f; scene->texture_ref = NULL; scene->total_texture_refs = 0; scene->texnum_sun = -1; scene->texnum_moon = -1; scene->texnum_spotlightcast = -1; scene->sndsrc = NULL; scene->total_sndsrcs = 0; scene->player_control_panel = NULL; /* Reset initial GL states */ if(display != NULL) { StateGLResetAll(&display->state_gl); StateGLEnable(&display->state_gl, GL_CULL_FACE); StateGLFrontFace(&display->state_gl, GL_CCW); StateGLShadeModel(&display->state_gl, GL_FLAT); } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1); /* Allocate the Messages List */ scene->total_messages = 6; /* Maximum of 6 at one time */ free(scene->message); scene->message = (char **)calloc( scene->total_messages, sizeof(char *) ); if(scene->message == NULL) scene->total_messages = 0; scene->message_display_until = 0; scene->camera_ref_title_display_until = 0; /* Allocate the FDM Realm */ scene->realm = SFMInit(0, NULL); if(scene->realm == NULL) { fprintf( stderr, "SARSceneLoadFromFile(): Error: Unable to create FDM Realm.\n" ); } else { SFMRealmStruct *realm = scene->realm; /* Set up FDM realm values */ realm->lapsed_time = 0; realm->time_compensation = 1.0f; realm->time_compression = 1.0f; realm->gravity = SFMDefaultGravity; /* Set up realm callback data and callback function ptrs */ realm->init_model_cb_client_data = core_ptr; realm->init_model_cb = SARSimInitModelCB; realm->destroy_model_cb_client_data = core_ptr; realm->destroy_model_cb = SARSimDestroyModelCB; realm->airborne_cb_client_data = core_ptr; realm->airborne_cb = SARSimAirborneCB; realm->touch_down_cb_client_data = core_ptr; realm->touch_down_cb = SARSimTouchDownCB; realm->overspeed_cb_client_data = core_ptr; realm->overspeed_cb = SARSimOverspeedCB; realm->collision_cb_client_data = core_ptr; realm->collision_cb = SARSimCollisionCB; } #define APPEND_TEXTURE(_t_) { \ const int n = MAX(scene->total_texture_refs, 0); \ scene->total_texture_refs = n + 1; \ scene->texture_ref = (v3d_texture_ref_struct **)realloc( \ scene->texture_ref, \ scene->total_texture_refs * sizeof(v3d_texture_ref_struct *) \ ); \ if(scene->texture_ref == NULL) { \ scene->total_texture_refs = 0; \ return(-3); \ } \ scene->texture_ref[n] = (_t_); \ } /* Render built in textures */ if(True) { #if 0 v3d_texture_ref_struct *t = SARCreateBladeBlurTexture( SAR_STD_TEXNAME_ROTOR_BLADE_BLUR, 0.98f ); APPEND_TEXTURE(t); #endif } /* Load all textures specified in the global Textures List */ if(True) { const char *name, *path; char *full_path; const sar_texture_name_struct *tn; const int tex_fmt = V3D_TEX_FORMAT_RGBA; /* Iterate through each Texture Name in the Textures List */ for(i = 0; i < core_ptr->total_texture_list; i++) { tn = core_ptr->texture_list[i]; if(tn == NULL) continue; name = tn->name; path = tn->filename; if((name == NULL) || (path == NULL)) continue; if(ISPATHABSOLUTE(path)) { full_path = STRDUP(path); } else { full_path = STRDUP(PrefixPaths( dname.local_data, path )); if((full_path != NULL) ? stat(full_path, &stat_buf) : True) { free(full_path); full_path = STRDUP(PrefixPaths( dname.global_data, path )); } } if(full_path != NULL) { v3d_texture_ref_struct *t = V3DTextureLoadFromFile2DPreempt( full_path, name, tex_fmt ); V3DTexturePriority(t, tn->priority); APPEND_TEXTURE(t); free(full_path); } else { fprintf( stderr, "%s: Warning: Unable to complete texture \"%s\" path \"%s\".\n", filename, name, path ); } } } /* Set references to frequently used global textures */ if(True) { scene->texnum_sun = SARGetTextureRefNumberByName( scene, SAR_STD_TEXNAME_SUN ); scene->texnum_moon = SARGetTextureRefNumberByName( scene, SAR_STD_TEXNAME_MOON ); scene->texnum_spotlightcast = SARGetTextureRefNumberByName( scene, SAR_STD_TEXNAME_SPOTLIGHTCAST ); } #undef APPEND_TEXTURE /* Create default global sound sources list */ if(True) { #define LOAD_SNDSRC(name,filename,filename_far,range,range_far) \ { \ i = MAX(scene->total_sndsrcs, 0); \ scene->total_sndsrcs = i + 1; \ scene->sndsrc = (sar_sound_source_struct **)realloc( \ scene->sndsrc, \ scene->total_sndsrcs * sizeof(sar_sound_source_struct *) \ ); \ if(scene->sndsrc == NULL) \ { \ scene->total_sndsrcs = 0; \ } \ else \ { \ char *s, *full_path, *full_path_far; \ \ /* Complete Filenames */ \ s = STRDUP(PrefixPaths(dname.local_data, filename)); \ if((s != NULL) ? stat(s, &stat_buf) : True) { \ free(s); \ s = STRDUP(PrefixPaths(dname.global_data, filename)); \ } \ full_path = s; \ \ s = STRDUP(PrefixPaths(dname.local_data, filename_far)); \ if((s != NULL) ? stat(s, &stat_buf) : True) { \ free(s); \ s = STRDUP(PrefixPaths(dname.global_data, filename_far)); \ } \ full_path_far = s; \ \ /* Check if file exists */ \ if((full_path != NULL) ? stat(full_path, &stat_buf) : True) \ fprintf(stderr, \ "SARSceneLoadFromFile(): Warning: Unable to find sound file \"%s\"\n",\ filename \ ); \ if((full_path_far != NULL) ? stat(full_path_far, &stat_buf) : True) \ fprintf(stderr, \ "SARSceneLoadFromFile(): Warning: Unable to find sound file \"%s\"\n",\ filename_far \ ); \ \ /* Create sound source */ \ scene->sndsrc[i] = SARSoundSourceNew( \ name, full_path, full_path_far, \ range, range_far, \ NULL, 0.0f, NULL, \ 0 /* Sample rate limit in Hz */ \ ); \ \ free(full_path); \ free(full_path_far); \ } \ } /* Gound Contact Sounds */ LOAD_SNDSRC( "land_wheel_skid", SAR_DEF_SOUND_LAND_WHEEL_SKID, SAR_DEF_SOUND_LAND_WHEEL_SKID, 600.0f, 400.0f ); LOAD_SNDSRC( "land_ski_skid", SAR_DEF_SOUND_LAND_SKI_SKID, SAR_DEF_SOUND_LAND_SKI_SKID, 600.0f, 400.0f ); LOAD_SNDSRC( "land_ski", SAR_DEF_SOUND_LAND_SKI, SAR_DEF_SOUND_LAND_SKI, 600.0f, 400.0f ); LOAD_SNDSRC( "land_belly", SAR_DEF_SOUND_LAND_BELLY, SAR_DEF_SOUND_LAND_BELLY, 1200.0f, 900.0f ); /* Thud Sounds */ LOAD_SNDSRC( "thud_light", SAR_DEF_SOUND_THUD_LIGHT, SAR_DEF_SOUND_THUD_LIGHT, 600.0f, 400.0f ); LOAD_SNDSRC( "thud_medium", SAR_DEF_SOUND_THUD_MEDIUM, SAR_DEF_SOUND_THUD_MEDIUM, 600.0f, 400.0f ); LOAD_SNDSRC( "thud_heavy", SAR_DEF_SOUND_THUD_HEAVY, SAR_DEF_SOUND_THUD_HEAVY, 600.0f, 400.0f ); /* Crash & Collision Sounds */ LOAD_SNDSRC( "crash_obstruction", SAR_DEF_SOUND_CRASH_OBSTRUCTION, SAR_DEF_SOUND_CRASH_OBSTRUCTION, 3300.0f, /* About 2 miles */ 2500.0f ); LOAD_SNDSRC( "crash_ground", SAR_DEF_SOUND_CRASH_GROUND, SAR_DEF_SOUND_CRASH_GROUND, 3300.0f, /* About 2 miles */ 2500.0f ); LOAD_SNDSRC( "splash_aircraft", SAR_DEF_SOUND_SPLASH_AIRCRAFT, SAR_DEF_SOUND_SPLASH_AIRCRAFT, 2500.0f, /* About 1.5 miles */ 2000.0f ); LOAD_SNDSRC( "splash_human", SAR_DEF_SOUND_SPLASH_HUMAN, SAR_DEF_SOUND_SPLASH_HUMAN, 600.0f, 400.0f ); #undef LOAD_SNDSRC } /* Create the Horizon */ horizon_ptr = &scene->horizon; horizon_ptr->last_tod = -1; /* Reset to -1 so horizon gets updated */ horizon_ptr->texture = NULL; horizon_ptr->total_textures = 0; /* Generate weather settings from the specified Weather Data * Entry */ SARWeatherSetScenePreset( core_ptr->weather_data, scene, weather_preset_name ); /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; ptype = *(int *)p; if(progress_func != NULL) { if(progress_func(client_data, i + 1, total_parms)) break; } /* Handle by parm type */ switch(ptype) { case SAR_PARM_VERSION: p_version = (sar_parm_version_struct *)p; if((p_version->major > PROG_VERSION_MAJOR) || (p_version->minor > PROG_VERSION_MINOR) || (p_version->release > PROG_VERSION_RELEASE) ) { int need_warn = 0; if(p_version->major > PROG_VERSION_MAJOR) need_warn = 1; else if((p_version->major == PROG_VERSION_MAJOR) && (p_version->minor > PROG_VERSION_MINOR) ) need_warn = 1; else if((p_version->major == PROG_VERSION_MAJOR) && (p_version->minor == PROG_VERSION_MINOR) && (p_version->release == PROG_VERSION_RELEASE) ) need_warn = 1; if(need_warn) fprintf( stderr, "%s: Warning: File format version %i.%i.%i is newer than program\ version %i.%i.%i.", filename, p_version->major, p_version->minor, p_version->release, PROG_VERSION_MAJOR, PROG_VERSION_MINOR, PROG_VERSION_RELEASE ); } break; case SAR_PARM_NAME: p_name = (sar_parm_name_struct *)p; free(scene->title); scene->title = STRDUP(p_name->name); break; case SAR_PARM_DESCRIPTION: p_description = (sar_parm_description_struct *)p; break; case SAR_PARM_PLAYER_MODEL_FILE: p_player_model_file = (sar_parm_player_model_file_struct *)p; break; case SAR_PARM_WEATHER: p_weather = (sar_parm_weather_struct *)p; break; case SAR_PARM_REGISTER_LOCATION: p_register_location = (sar_parm_register_location_struct *)p; break; case SAR_PARM_SCENE_GPS: p_scene_gps = (sar_parm_scene_gps_struct *)p; scene->dms_x_offset = p_scene_gps->dms_x_offset; scene->dms_y_offset = p_scene_gps->dms_y_offset; scene->planet_radius = p_scene_gps->planet_radius; break; case SAR_PARM_SCENE_MAP: p_scene_map = (sar_parm_scene_map_struct *)p; break; case SAR_PARM_SCENE_ELEVATION: p_scene_elevation = (sar_parm_scene_elevation_struct *)p; scene->msl_elevation = p_scene_elevation->elevation; break; case SAR_PARM_SCENE_CANT: p_scene_cant = (sar_parm_scene_cant_struct *)p; scene->cant_angle = p_scene_cant->cant; break; case SAR_PARM_SCENE_GROUND_FLAGS: p_scene_ground_flags = (sar_parm_scene_ground_flags_struct *)p; scene->base_flags = (sar_scene_base_flags)p_scene_ground_flags->flags; break; case SAR_PARM_SCENE_GROUND_TILE: p_scene_ground_tile = (sar_parm_scene_ground_tile_struct *)p; if(True) { float min, max; GLuint list; sar_visual_model_struct **vmodel; v3d_texture_ref_struct *t = NULL; /* Close range tiling size and range */ scene->base.tile_width = ((p_scene_ground_tile->tile_width > 0) ? p_scene_ground_tile->tile_width : SAR_DEF_GROUND_BASE_TILE_WIDTH ); scene->base.tile_height = ((p_scene_ground_tile->tile_height > 0) ? p_scene_ground_tile->tile_height : SAR_DEF_GROUND_BASE_TILE_HEIGHT ); scene->base.close_range = ((p_scene_ground_tile->close_range > 0) ? p_scene_ground_tile->close_range : SAR_DEF_GROUND_BASE_TILE_CLOSE_RANGE ); /* Far solid color */ memcpy( &scene->base.color, &p_scene_ground_tile->color, sizeof(sar_color_struct) ); /* Select texture */ t = SARGetTextureRefByName(scene, p_scene_ground_tile->texture_name); /* Create the simple/far Ground Base Visual Model * as needed */ vmodel = &scene->base.visual_model_simple; if(*vmodel != NULL) { fprintf( stderr, "%s: Warning: Ground base simple/far visual model is already defined.\n", filename ); } else { /* Create new visual model */ *vmodel = SARVisualModelNew( scene, NULL, NULL ); /* (Re)generate GL list on visual model structure */ list = (GLuint)SARVisualModelNewList(*vmodel); if(list != 0) { /* Mark visual model as loading */ (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADING; /* Begin recording new list */ glNewList(list, GL_COMPILE); { /* Far (big) ground base tiles */ min = -(SAR_MAX_VISIBILITY_DISTANCE + (0.25 * SAR_MAX_VISIBILITY_DISTANCE)); max = (SAR_MAX_VISIBILITY_DISTANCE + (0.25 * SAR_MAX_VISIBILITY_DISTANCE)); SARObjGenerateTilePlane( min, max, /* Min and max */ (float)(max / 4), /* Tile width and height */ (float)(max / 4) ); } glEndList(); /* Mark visual model as done loading */ (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADED; } } /* Create the detailed/near Ground Base Visual Model * as needed */ vmodel = &scene->base.visual_model_close; if(*vmodel != NULL) { fprintf( stderr, "%s: Warning: Ground base detailed/near visual model is already defined.\n", filename ); } else { /* Create new visual model */ *vmodel = SARVisualModelNew( scene, NULL, NULL ); /* (Re)generate GL list on visual model structure */ list = (GLuint)SARVisualModelNewList(*vmodel); if(list != 0) { /* Mark visual model as loading */ (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADING; /* Begin recording new list */ glNewList(list, GL_COMPILE); { /* Select tiled ground texture if defined, if * no texture then a texture unselect will be * recorded. */ V3DTextureSelect(t); /* Generate close range textured tiles */ SARObjGenerateTilePlane( -scene->base.close_range, /* Min */ scene->base.close_range, /* Max */ (float)scene->base.tile_width, /* Tile width */ (float)scene->base.tile_height /* Tile height */ ); } glEndList(); /* Mark visual model as done loading */ (*vmodel)->load_state = SAR_VISUAL_MODEL_LOADED; } } } break; case SAR_PARM_TEXTURE_BASE_DIRECTORY: p_texture_base_directory = (sar_parm_texture_base_directory_struct *)p; break; case SAR_PARM_TEXTURE_LOAD: p_texture_load = (sar_parm_texture_load_struct *)p; SARObjLoadTexture( core_ptr, scene, p_texture_load ); break; /* Skip mission parms */ case SAR_PARM_NEW_OBJECT: p_new_object = (sar_parm_new_object_struct *)p; obj_num = SARObjNew( scene, ptr, total, p_new_object->object_type ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; /* Reset all substructure type pointers */ DO_RESET_SUBSTRUCTURE_PTRS if(obj_ptr != NULL) { /* Get pointer to substructure */ switch(obj_ptr->type) { case SAR_OBJ_TYPE_GARBAGE: case SAR_OBJ_TYPE_STATIC: case SAR_OBJ_TYPE_AUTOMOBILE: case SAR_OBJ_TYPE_WATERCRAFT: break; case SAR_OBJ_TYPE_AIRCRAFT: obj_aircraft_ptr = SAR_OBJ_GET_AIRCRAFT(obj_ptr); break; case SAR_OBJ_TYPE_GROUND: obj_ground_ptr = SAR_OBJ_GET_GROUND(obj_ptr); break; case SAR_OBJ_TYPE_RUNWAY: case SAR_OBJ_TYPE_HELIPAD: case SAR_OBJ_TYPE_HUMAN: case SAR_OBJ_TYPE_SMOKE: case SAR_OBJ_TYPE_FIRE: case SAR_OBJ_TYPE_EXPLOSION: case SAR_OBJ_TYPE_CHEMICAL_SPRAY: case SAR_OBJ_TYPE_FUELTANK: case SAR_OBJ_TYPE_PREMODELED: break; } } break; case SAR_PARM_NEW_HELIPAD: p_new_helipad = (sar_parm_new_helipad_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjLoadHelipad( core_ptr, scene, p_new_helipad ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; obj_helipad_ptr = SAR_OBJ_GET_HELIPAD(obj_ptr); break; case SAR_PARM_NEW_RUNWAY: p_new_runway = (sar_parm_new_runway_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjLoadRunway( core_ptr, scene, p_new_runway ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; obj_runway_ptr = SAR_OBJ_GET_RUNWAY(obj_ptr); break; case SAR_PARM_NEW_HUMAN: p_new_human = (sar_parm_new_human_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjLoadHuman( core_ptr, scene, p_new_human ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; obj_human_ptr = SAR_OBJ_GET_HUMAN(obj_ptr); break; case SAR_PARM_NEW_FIRE: p_new_fire = (sar_parm_new_fire_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjLoadFire( core_ptr, scene, p_new_fire ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; obj_fire_ptr = SAR_OBJ_GET_FIRE(obj_ptr); break; case SAR_PARM_NEW_SMOKE: p_new_smoke = (sar_parm_new_smoke_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjLoadSmoke( core_ptr, scene, p_new_smoke ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; obj_smoke_ptr = SAR_OBJ_GET_SMOKE(obj_ptr); break; case SAR_PARM_NEW_PREMODELED: p_new_premodeled = (sar_parm_new_premodeled_struct *)p; DO_RESET_SUBSTRUCTURE_PTRS obj_num = SARObjPremodeledNew( core_ptr, scene, p_new_premodeled->model_type, p_new_premodeled->argc, p_new_premodeled->argv ); obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; break; case SAR_PARM_MODEL_FILE: p_model_file = (sar_parm_model_file_struct *)p; if((p_model_file->file != NULL) && (obj_ptr != NULL)) SARObjLoadFromFile(core_ptr, obj_num, p_model_file->file); break; case SAR_PARM_RANGE: p_range = (sar_parm_range_struct *)p; if(obj_ptr != NULL) { obj_ptr->range = (float)MAX(p_range->range, 0.0); } break; case SAR_PARM_RANGE_FAR: p_range_far = (sar_parm_range_far_struct *)p; if(obj_ptr != NULL) { obj_ptr->range_far = (float)MAX(p_range_far->range_far, 0.0); } break; case SAR_PARM_TRANSLATE: p_translate = (sar_parm_translate_struct *)p; SARObjLoadTranslate( core_ptr, scene, obj_ptr, p_translate ); break; case SAR_PARM_TRANSLATE_RANDOM: p_translate_random = (sar_parm_translate_random_struct *)p; /* Ignore this, for missions only) */ break; case SAR_PARM_ROTATE: p_rotate = (sar_parm_rotate_struct *)p; if(obj_ptr != NULL) { SARSimWarpObject( scene, obj_ptr, NULL, &p_rotate->rotate ); } break; case SAR_PARM_NO_DEPTH_TEST: p_no_depth_test = (sar_parm_no_depth_test_struct *)p; if(obj_ptr != NULL) { obj_ptr->flags |= SAR_OBJ_FLAG_NO_DEPTH_TEST; } break; case SAR_PARM_POLYGON_OFFSET: p_polygon_offset = (sar_parm_polygon_offset_struct *)p; if(obj_ptr != NULL) { obj_ptr->flags |= p_polygon_offset->flags; } break; case SAR_PARM_CONTACT_BOUNDS_SPHERICAL: p_contact_bounds_spherical = (sar_parm_contact_bounds_spherical_struct *)p; if(obj_ptr != NULL) { sar_contact_bounds_struct *cb = obj_ptr->contact_bounds; SARObjAddContactBoundsSpherical( obj_ptr, (cb != NULL) ? cb->crash_flags : 0, (cb != NULL) ? cb->crash_type : 0, p_contact_bounds_spherical->radius ); } break; case SAR_PARM_CONTACT_BOUNDS_CYLENDRICAL: p_contact_bounds_cylendrical = (sar_parm_contact_bounds_cylendrical_struct *)p; if(obj_ptr != NULL) { sar_contact_bounds_struct *cb = obj_ptr->contact_bounds; SARObjAddContactBoundsCylendrical( obj_ptr, (cb != NULL) ? cb->crash_flags : 0, (cb != NULL) ? cb->crash_type : 0, p_contact_bounds_cylendrical->radius, p_contact_bounds_cylendrical->height_min, p_contact_bounds_cylendrical->height_max ); } break; case SAR_PARM_CONTACT_BOUNDS_RECTANGULAR: p_contact_bounds_rectangular = (sar_parm_contact_bounds_rectangular_struct *)p; if(obj_ptr != NULL) { sar_contact_bounds_struct *cb = obj_ptr->contact_bounds; SARObjAddContactBoundsRectangular( obj_ptr, (cb != NULL) ? cb->crash_flags : 0, (cb != NULL) ? cb->crash_type : 0, p_contact_bounds_rectangular->x_min, p_contact_bounds_rectangular->x_max, p_contact_bounds_rectangular->y_min, p_contact_bounds_rectangular->y_max, p_contact_bounds_rectangular->z_min, p_contact_bounds_rectangular->z_max ); } break; case SAR_PARM_GROUND_ELEVATION: p_ground_elevation = (sar_parm_ground_elevation_struct *)p; if(obj_ground_ptr != NULL) { obj_ground_ptr->elevation = p_ground_elevation->elevation; } else { fprintf( stderr, "%s: Warning:\ Unable to set ground elevation for object not of type \"%i\".\n", filename, SAR_OBJ_TYPE_GROUND ); } break; case SAR_PARM_OBJECT_NAME: p_object_name = (sar_parm_object_name_struct *)p; if(obj_ptr != NULL) { free(obj_ptr->name); obj_ptr->name = STRDUP(p_object_name->name); } break; case SAR_PARM_OBJECT_MAP_DESCRIPTION: p_object_map_description = (sar_parm_object_map_description_struct *)p; if(obj_ptr != NULL) { /* Ignore this */ } break; case SAR_PARM_FUEL: p_fuel = (sar_parm_fuel_struct *)p; if(obj_aircraft_ptr != NULL) { /* Set current fuel */ obj_aircraft_ptr->fuel = p_fuel->fuel; /* Set max only if not negative */ if(p_fuel->fuel_max >= 0.0) obj_aircraft_ptr->fuel_max = p_fuel->fuel_max; /* Sanitize current */ if(obj_aircraft_ptr->fuel > obj_aircraft_ptr->fuel_max) obj_aircraft_ptr->fuel = obj_aircraft_ptr->fuel_max; } break; case SAR_PARM_HITPOINTS: p_hitpoints = (sar_parm_hitpoints_struct *)p; if(obj_ptr != NULL) { /* Set current hit points */ obj_ptr->hit_points = p_hitpoints->hitpoints; /* Set max only if not negative */ if(p_hitpoints->hitpoints_max >= 0.0) obj_ptr->hit_points_max = p_hitpoints->hitpoints_max; /* Sanitize current */ if(obj_ptr->hit_points > obj_ptr->hit_points_max) obj_ptr->hit_points = obj_ptr->hit_points_max; } break; case SAR_PARM_ENGINE_STATE: p_engine_state = (sar_parm_engine_state_struct *)p; /* TODO Work on this later */ break; case SAR_PARM_PASSENGERS: p_passengers = (sar_parm_passengers_struct *)p; /* TODO Work on this later */ break; case SAR_PARM_RUNWAY_APPROACH_LIGHTING_NORTH: p_runway_applight_n = (sar_parm_runway_approach_lighting_north_struct *)p; if((obj_ptr != NULL) && (obj_runway_ptr != NULL)) { obj_runway_ptr->north_approach_lighting_flags = p_runway_applight_n->flags; } break; case SAR_PARM_RUNWAY_APPROACH_LIGHTING_SOUTH: p_runway_applight_s = (sar_parm_runway_approach_lighting_south_struct *)p; if((obj_ptr != NULL) && (obj_runway_ptr != NULL)) { obj_runway_ptr->south_approach_lighting_flags = p_runway_applight_s->flags; } break; case SAR_PARM_HUMAN_MESSAGE_ENTER: p_human_message_enter = (sar_parm_human_message_enter_struct *)p; if((obj_ptr != NULL) && (obj_human_ptr != NULL)) { free(obj_human_ptr->mesg_enter); obj_human_ptr->mesg_enter = STRDUP( p_human_message_enter->message ); } break; case SAR_PARM_HUMAN_REFERENCE: p_human_reference = (sar_parm_human_reference_struct *)p; if((obj_ptr != NULL) && (obj_human_ptr != NULL) && (p_human_reference->reference_name != NULL) ) { int human_ref_obj_num = -1; const char *ref_name = (const char *)p_human_reference->reference_name; /* Run towards? */ if(p_human_reference->flags & SAR_HUMAN_FLAG_RUN_TOWARDS) { obj_human_ptr->flags |= SAR_HUMAN_FLAG_RUN_TOWARDS; } /* Run away? */ else if(p_human_reference->flags & SAR_HUMAN_FLAG_RUN_AWAY) { obj_human_ptr->flags |= SAR_HUMAN_FLAG_RUN_AWAY; } /* Handle reference object name */ if(!strcasecmp(ref_name, "player")) { /* Set special intercept code to intercept the player */ obj_human_ptr->intercepting_object = -2; } else { /* All else match by object name */ SARObjMatchPointerByName( scene, *ptr, *total, ref_name, &human_ref_obj_num ); obj_human_ptr->intercepting_object = human_ref_obj_num; } } break; } /* Handle by parm type */ } /* Iterate through loaded parms */ /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); #undef DO_RESET_SUBSTRUCTURE_PTRS return(0); } searchandrescue_1.7.0/sar/sarmenuop.c0000664000175000001440000001671312046776402016754 0ustar jesseusers#include #include #include #include "menu.h" #include "sar.h" #include "sarmenuop.h" void SARMenuSwitchToMenu(sar_core_struct *core_ptr, const char *name); sar_menu_list_struct *SARMenuGetList( sar_menu_struct *m, int skip, int *list_num ); sar_menu_spin_struct *SARMenuGetSpin( sar_menu_struct *m, int skip, int *spin_num ); sar_menu_list_item_struct *SARMenuListGetSelectedItem( sar_menu_struct *m, int id ); char *SARMenuGetCurrentMenuName(sar_core_struct *core_ptr); #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) /* * Switches to the specified menu. * * If no menu is specified (name=NULL) then simulation will * begin. */ void SARMenuSwitchToMenu(sar_core_struct *core_ptr, const char *name) { int new_menu_num, old_menu_num; gw_display_struct *display; const sar_option_struct *opt; if(core_ptr == NULL) return; display = core_ptr->display; opt = &core_ptr->option; /* Record previous menu number */ old_menu_num = core_ptr->cur_menu; /* No specified menu to switch to? */ if(name == NULL) { /* This implies we are going out of the menu system and * entering simulation */ sar_menu_struct *old_menu = SARIsMenuAllocated(core_ptr, old_menu_num) ? core_ptr->menu[old_menu_num] : NULL; /* Unload image on old menu */ /* if(opt->prioritize_memory && (old_menu != NULL)) */ if(old_menu != NULL) SARMenuUnloadBackgroundImage(old_menu); /* Unselect current menu on core structure, indicating that * no menu is selected and that we are not in the menus */ core_ptr->cur_menu = -1; /* Skip redrawing, since redrawing would be done rather * frequently during the simulation */ /* GWPostRedraw(display); */ return; } /* Get the number of the menu that we want to switch to */ new_menu_num = SARMatchMenuByName(core_ptr, name); /* Got match and matched menu number is different from the one * currently selected? */ if((new_menu_num > -1) && (new_menu_num != core_ptr->cur_menu)) { sar_menu_struct *old_menu = SARIsMenuAllocated(core_ptr, old_menu_num) ? core_ptr->menu[old_menu_num] : NULL; sar_menu_struct *new_menu = SARIsMenuAllocated(core_ptr, new_menu_num) ? core_ptr->menu[new_menu_num] : NULL; const char *old_bg_image_path = (old_menu != NULL) ? old_menu->bg_image_path : NULL, *new_bg_image_path = (new_menu != NULL) ? new_menu->bg_image_path : NULL; GWSetInputBusy(display); /* Reset values on the previous menu */ /* if(old_menu != NULL) { } */ /* Check if background images are the same on both old and * new menus by comparing the background image paths (if * defined) */ if(((old_bg_image_path != NULL) && (new_bg_image_path != NULL)) ? ((old_menu->bg_image != NULL) ? !strcmp(old_bg_image_path, new_bg_image_path) : False) : False ) { /* Image paths are the same, so unload the image on the * new menu and transfer the image from the old menu to * the new menu * * Mark the old menu's image NULL after transfer so * that it dosen't get referenced again * * Note that both new_menu and old_menu are known to be * not NULL from the above check */ SARMenuUnloadBackgroundImage(new_menu); if(new_menu->bg_image == NULL) { new_menu->bg_image = old_menu->bg_image; old_menu->bg_image = NULL; } } else { /* Image paths are different, so unload background image * on old menu and load new background image on new menu */ /* if(opt->prioritize_memory && (old_menu != NULL)) */ if(old_menu != NULL) SARMenuUnloadBackgroundImage(old_menu); if(opt->menu_backgrounds && ((new_menu != NULL) ? (new_menu->bg_image == NULL) : False) ) SARMenuLoadBackgroundImage(new_menu); } glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); GWSwapBuffer(core_ptr->display); GWFlush(core_ptr->display); /* Is the new menu valid? */ if(new_menu != NULL) { /* New menu is valid, so switch to it */ int n; void *o; sar_menu_button_struct *btn; sar_menu_struct *m = new_menu; /* Begin resetting object values on the new menu */ for(n = 0; n < m->total_objects; n++) { o = m->object[n]; if(o == NULL) continue; switch(SAR_MENU_OBJECT_TYPE(o)) { case SAR_MENU_OBJECT_TYPE_BUTTON: btn = SAR_MENU_BUTTON(o); btn->state = SAR_MENU_BUTTON_STATE_UNARMED; break; case SAR_MENU_OBJECT_TYPE_PROGRESS: SARMenuProgressSet( display, m, n, 0.0f, False ); break; } } /* Select first object on menu */ m->selected_object = 0; /* Update index number of the current menu */ core_ptr->cur_menu = new_menu_num; } /* Redraw */ GWPostRedraw(display); /* Mark input as ready */ GWSetInputReady(display); } } /* * Returns the pointer to the list object on the menu, * skipping the indicated number of lists. * * Can return NULL for no match. */ sar_menu_list_struct *SARMenuGetList( sar_menu_struct *m, int skip, int *list_num ) { int i; void *ptr; sar_menu_list_struct *list_ptr; if(m == NULL) return(NULL); if(list_num != NULL) *list_num = -1; for(i = 0; i < m->total_objects; i++) { ptr = m->object[i]; if(ptr == NULL) continue; if(*(int *)ptr != SAR_MENU_OBJECT_TYPE_LIST) continue; /* Get pointer to list object. */ list_ptr = ptr; /* Skip this list object? */ if(skip > 0) { skip--; continue; } else { if(list_num != NULL) *list_num = i; return(list_ptr); } } return(NULL); } /* * Returns the pointer to the spin object on the menu, * skipping the indicated number of spin objects. * * Can return NULL for no match. */ sar_menu_spin_struct *SARMenuGetSpin( sar_menu_struct *m, int skip, int *spin_num ) { int i; void *ptr; sar_menu_spin_struct *spin_ptr; if(m == NULL) return(NULL); if(spin_num != NULL) *spin_num = -1; for(i = 0; i < m->total_objects; i++) { ptr = m->object[i]; if(ptr == NULL) continue; if(*(int *)ptr != SAR_MENU_OBJECT_TYPE_SPIN) continue; /* Get pointer to spin object. */ spin_ptr = ptr; /* Skip this spin object? */ if(skip > 0) { skip--; continue; } else { if(spin_num != NULL) *spin_num = i; return(spin_ptr); } } return(NULL); } /* * Returns the pointer to the selected list item on the list object * on the menu, skipping the indicated number of list objects. */ sar_menu_list_item_struct *SARMenuListGetSelectedItem( sar_menu_struct *m, int id ) { int i; sar_menu_list_struct *list = SAR_MENU_LIST( SARMenuGetObjectByID(m, id, NULL) ); if(list == NULL) return(NULL); i = list->selected_item; if((i >= 0) && (i < list->total_items)) return(list->item[i]); else return(NULL); } /* * Returns the pointer to the name of the currently selected * menu or NULL on failure. */ char *SARMenuGetCurrentMenuName(sar_core_struct *core_ptr) { int cur_menu; sar_menu_struct *m; if(core_ptr == NULL) return(NULL); cur_menu = core_ptr->cur_menu; if(SARIsMenuAllocated(core_ptr, cur_menu)) m = core_ptr->menu[cur_menu]; else return(NULL); return(m->name); } searchandrescue_1.7.0/sar/sarcamp.c0000644000175000001440000003254613452215245016364 0ustar jesseusers/* These functions create a campaign mission file. See sarcamp.h for details on how the functions work. */ #include #include #include #include "sarcamp.h" FILE *Create_Campaign_File() { char *filename; FILE *camp_file; filename = Get_Campaign_Filename(); if (! filename) return NULL; camp_file = fopen(filename, "w"); if (! camp_file) printf("Unable to open file %s\n", filename); free(filename); return camp_file; } char *Create_Campaign_Weather() { char *weather_string; int random_num; weather_string = (char *) calloc(64, sizeof(char)); if (! weather_string) return NULL; random_num = rand() % 8; switch (random_num) { case 0: strcpy(weather_string, "weather Clear"); break; case 1: strcpy(weather_string, "weather Hazy"); break; case 2: strcpy(weather_string, "weather Scattered"); break; case 3: strcpy(weather_string, "weather Cloudy"); break; case 4: strcpy(weather_string, "weather Overcast"); break; case 5: strcpy(weather_string, "weather Foggy"); break; case 6: strcpy(weather_string, "weather Stormy Sparse"); break; case 7: strcpy(weather_string, "weather Stormy Dense"); break; } return weather_string; } char *Create_Campaign_Scenery() { char *scene_file; scene_file = (char *) calloc(128, sizeof(char)); if (! scene_file) return NULL; strcpy(scene_file, "mission_scene_file scenery/los_angeles.scn"); return scene_file; } int Create_Campaign_Start_Point() { int start_number; start_number = (rand() % MAX_PLACES) + 1; return start_number; } char *Create_Campaign_Description(int first_objective) { char *buffer; char *place_name; buffer = (char *) calloc(1024, sizeof(char)); if (! buffer) return NULL; strcpy(buffer, "name Mission: Patrol\n"); strcat(buffer, "description "); if (first_objective == LOCATION_SEARCH) strcat(buffer, "Search the local area (in a 5 mile radius) for an accident victim.\n"); else { place_name = Get_Location_Name(first_objective); if (place_name) { strcat(buffer, "Fly to "); strcat(buffer, place_name); strcat(buffer, ".\n"); free(place_name); } } return buffer; } int Get_Coordinates(int location, int *x, int *y) { int status = True; switch (location) { case LOCATION_LAX: *x = -5430 ; *y = 35750; break; case LOCATION_SMO: *x = -7300; *y = 42580; break; case LOCATION_UCLA: *x = -4920; *y = 44800; break; case LOCATION_CAT: *x = -4931; *y = -25183; break; case LOCATION_USCG: *x = -23758; *y = 34647; break; case LOCATION_ENTERPRISE: *x = -4130; *y = -9320; break; default: status = False; break; } return status; } /* char *Place_Campaign_Ship() { char *buffer; buffer = (char *) calloc(4096, sizeof(char)); if (! buffer) return NULL; strcpy(buffer, "create_object 3\n"); strcat(buffer, "model_file vessels/uscg378.3d\n"); strcat(buffer, "translation -23758.0 34647.0 0.0\n"); strcat(buffer, "rotate 300 0 0\n"); strcat(buffer, "object_name uscg378_01\n"); strcat(buffer, "create_helipad vehicle 29.0 18.0 3.2 USCG y y y y y uscg378_01 0.0 -58.5 36.0 0.0 0.0 0.0\n"); strcat(buffer, "object_name helipad_uscg\n"); strcat(buffer, "object_map_description Coast Guard helipad\n"); strcat(buffer, "range 2200\n"); return buffer; } */ char *Place_Campaign_Humans(int start_place, int *destinations) { char *buffer; char coordinates[256]; int objective = 0; int last_location = start_place; int place_x = 0, place_y = 0; int human_x, human_y; buffer = (char *) calloc(4096, sizeof(char)); if (! buffer) return NULL; strcpy(buffer, "# Place humans\n"); while (objective < MAX_OBJECTIVES) { if (destinations[objective] == LOCATION_SEARCH) { // are we over water or land? if ( (last_location == LOCATION_USCG) || (last_location == LOCATION_ENTERPRISE) ) strcat(buffer, "create_human default need_rescue alert aware in_water\n"); else strcat(buffer, "create_human default need_rescue alert aware\n"); strcat(buffer, "translation "); Get_Coordinates(last_location, &place_x, &place_y); human_x = (rand() % RESCUE_DISTANCE) - (RESCUE_DISTANCE / 2); human_x = place_x + human_x; human_y = (rand() & RESCUE_DISTANCE) - (RESCUE_DISTANCE / 2); human_y = place_y + human_y; sprintf(coordinates, "%d %d 0.0", human_x, human_y); strcat(buffer, coordinates); strcat(buffer, "\nset_human_mesg_enter Thank you for the lift.\n"); if (last_location == LOCATION_CAT) { strcat(buffer, "create_fire 10.0 15.0\n"); strcat(buffer, "translation "); sprintf(coordinates, "%d %d 0.0\n", human_x + 200, human_y - 100); strcat(buffer, coordinates); } } else if ( (destinations[objective] > LOCATION_NONE) && (destinations[objective] < LOCATION_SEARCH) ) last_location = destinations[objective]; objective++; } return buffer; } char *Create_Campaign_Aircraft(int all_arrivals) { char *craft_name; int aircraft_number; craft_name = (char *) calloc(128, sizeof(char)); if (! craft_name) return NULL; strcpy(craft_name, "player_model_file aircrafts/"); /* we can use any helicoptor for all arrival missions */ if (all_arrivals) aircraft_number = rand() % 8; else aircraft_number = rand() % 4; switch (aircraft_number) { case 0: strcat(craft_name, "hh60.3d"); break; case 1: strcat(craft_name, "hh65.3d"); break; case 2: strcat(craft_name, "ka27.3d"); break; case 3: strcat(craft_name, "v22.3d"); break; /* end of all types mission list. From here it's arrivals only */ case 4: strcat(craft_name, "as350.3d"); break; case 5: strcat(craft_name, "b47.3d"); break; case 6: strcat(craft_name, "s64.3d"); break; case 7: strcat(craft_name, "uh1d.3d"); break; } return craft_name; } char *Create_Campaign_Arrive_Objective(int current_location, int next_location) { char *buffer; char *location_name; buffer = (char *) calloc( 512, sizeof(char)); if (! buffer) return NULL; strcpy(buffer, "mission_objective_new arrive\n"); strcat(buffer, "mission_objective_time_left 0.0\n"); strcat(buffer, "mission_objective_arrive_at "); /* put in current location */ location_name = Get_Location_Symbol(current_location); if (location_name) { strcat(buffer, location_name); free(location_name); } strcat(buffer, "\n"); strcat(buffer, "mission_objective_message_success Welcome!"); location_name = Get_Location_Name(next_location); /* put in next location */ if (location_name) { strcat(buffer, " Next head for "); strcat(buffer, location_name); free(location_name); } strcat(buffer, "\nmission_objective_message_fail You did not arrive safely.\n"); return buffer; } char *Create_Campaign_Pickup_Objective(int next_location) { char *buffer; char *location_name; buffer = (char *) calloc(1024, sizeof(char)); if (! buffer) return NULL; strcpy(buffer, "mission_objective_new pick_up\n"); strcat(buffer, "mission_objective_time_left 0.0\n"); strcat(buffer, "mission_objective_humans_tally 1 1\n"); strcat(buffer, "mission_objective_message_success "); /* put next location in here */ location_name = Get_Location_Name(next_location); if (location_name) { strcat(buffer, "Pick up complete. Head for "); strcat(buffer, location_name); free(location_name); } strcat(buffer, "\nmission_objective_message_fail You were unable to complete pick-up.\n"); return buffer; } char *Get_Location_Symbol(int location) { char *my_string; my_string = (char *) calloc(64, sizeof(char)); if (! my_string) return NULL; switch (location) { case LOCATION_NONE: free(my_string); my_string = NULL; break; case LOCATION_LAX: strcpy(my_string, "helipad_lax"); break; case LOCATION_SMO: strcpy(my_string, "helipad_smo"); break; case LOCATION_UCLA: strcpy(my_string, "helipad_ucla"); break; case LOCATION_CAT: strcpy(my_string, "helipad_cat"); break; case LOCATION_USCG: strcpy(my_string, "helipad_uscg"); break; case LOCATION_ENTERPRISE: strcpy(my_string, "helipad_enterprise"); break; default: my_string[0] = '\0'; break; } return my_string; } char *Get_Location_Name(int location) { char *my_string; my_string = (char *) calloc(64, sizeof(char)); if (! my_string) return NULL; switch (location) { case LOCATION_NONE: free(my_string); my_string = NULL; break; case LOCATION_LAX: strcpy(my_string, "Los Angeles Airport"); break; case LOCATION_SMO: strcpy(my_string, "Santa Monica Airport"); break; case LOCATION_UCLA: strcpy(my_string, "UCLA Hospital"); break; case LOCATION_CAT: strcpy(my_string, "Catalina Airport"); break; case LOCATION_USCG: strcpy(my_string, "US Coast Guard ship"); break; case LOCATION_ENTERPRISE: strcpy(my_string, "Enterprise Carrier"); break; case LOCATION_SEARCH: strcpy(my_string, "a nearby victim"); break; } return my_string; } char *Get_Campaign_Filename() { char *full_filename; char *home_dir; home_dir = getenv("HOME"); if (! home_dir) return NULL; full_filename = (char *) calloc( strlen(home_dir) + 64, sizeof(char) ); if (! full_filename) return NULL; sprintf(full_filename, "%s/.SearchAndRescue/campaign.mis", home_dir); return full_filename; } int Create_Campaign() { FILE *camp_file; char *objective_string, *temp_string; int start_point; int objective_type, all_arrivals = True; int number_of_objectives; int done_description = False; int destination[MAX_OBJECTIVES]; int count; camp_file = Create_Campaign_File(); if (!camp_file) return False; memset(destination, 0, MAX_OBJECTIVES * sizeof(int)); start_point = Create_Campaign_Start_Point(); number_of_objectives = (rand() % 3) + 3; /* figure out where we will go */ count = 0; while (count < number_of_objectives) { if (count < (number_of_objectives - 1) ) objective_type = rand() % 2; else /* last one is always arrival */ objective_type = OBJECTIVE_ARRIVE; if (objective_type == OBJECTIVE_ARRIVE) { int done; int temp_place; do { temp_place = (rand() % MAX_PLACES) + 1; if ( (count == 0) && (temp_place == start_point) ) done = False; else if ( (count > 0) && (temp_place == destination[count - 1]) ) done = False; else done = True; } while (! done); destination[count] = temp_place; } else destination[count] = LOCATION_SEARCH; count++; } count = 0; while (count < number_of_objectives) { if (destination[count] == LOCATION_SEARCH) { objective_string = Create_Campaign_Pickup_Objective(destination[count + 1]); all_arrivals = False; } else objective_string = Create_Campaign_Arrive_Objective(destination[count], destination[count + 1]); if (! done_description) { temp_string = Create_Campaign_Description(destination[0]); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } temp_string = Create_Campaign_Weather(); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } temp_string = Create_Campaign_Scenery(); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } /* temp_string = Place_Campaign_Ship(); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } */ temp_string = Get_Location_Symbol(start_point); if (temp_string) { fprintf(camp_file, "mission_begin_at %s\n", temp_string); free(temp_string); } done_description = True; } if (objective_string) { fprintf(camp_file, "%s\n", objective_string); free(objective_string); } count++; } temp_string = Place_Campaign_Humans(start_point, destination); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } temp_string = Create_Campaign_Aircraft(all_arrivals); if (temp_string) { fprintf(camp_file, "%s\n", temp_string); free(temp_string); } fclose(camp_file); return True; } searchandrescue_1.7.0/sar/sarmemory.h0000664000175000001440000000110012046776413016750 0ustar jesseusers#ifndef SARMEMORY_H #define SARMEMORY_H #include "obj.h" #include "sar.h" /* * Memory stats structure: */ typedef struct _sar_memory_stat_struct sar_memory_stat_struct; struct _sar_memory_stat_struct { /* All memory units are in bytes unless noted otherwise */ unsigned long total, texture, vmodel, scene, object; int ntextures, nvmodels, nobjects; }; extern void SARMemoryStat( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct **object, int total_objects, sar_memory_stat_struct *stat_buf ); #endif /* SARMEMORY_H */ searchandrescue_1.7.0/sar/sarfioopen.c0000664000175000001440000020574712046776414017122 0ustar jesseusers#include #include #include #include #include #include "../include/cfgfmt.h" #include "../include/string.h" #include "../include/strexp.h" #include "../include/fio.h" #include "../include/disk.h" #include "obj.h" #include "mission.h" #include "sartime.h" #include "sarfio.h" #include "config.h" static const char *NEXT_ARG(const char *s); static void CHOP_STR_BLANK(char *s); static char *SARParmLoadFromFileGetParmString(FILE *fp); static int SARParmLoadFromFileIterate( const char *filename, void ***parm, int *total_parms, const char *parm_str, const char *val_str, int *lines_read, int filter_parm_type ); static int SARParmLoadFromFileScene( const char *filename, FILE *fp, void ***parm, int *total_parms, int filter_parm_type, void *client_data, int (*progress_func)(void *, long, long), long file_size, int *lines_read ); static int SARParmLoadFromFileMissionLog( const char *filename, FILE *fp, void ***parm, int *total_parms, int filter_parm_type, void *client_data, int (*progress_func)(void *, long, long), long file_size, int *lines_read ); int SARParmLoadFromFile( const char *filename, int file_format, void ***parm, int *total_parms, int filter_parm_type, void *client_data, int (*progress_func)(void *, long, long) ); #ifndef SAR_COMMENT_CHAR # define SAR_COMMENT_CHAR '#' #endif #define ATOI(s) (((s) != NULL) ? atoi(s) : 0) #define ATOL(s) (((s) != NULL) ? atol(s) : 0) #define ATOF(s) (((s) != NULL) ? (float)atof(s) : 0.0f) #define STRDUP(s) (((s) != NULL) ? strdup(s) : NULL) #define MAX(a,b) (((a) > (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define CLIP(a,l,h) (MIN(MAX((a),(l)),(h))) #define ISCOMMENT(c) ((c) == SAR_COMMENT_CHAR) #define ISCR(c) (((c) == '\n') || ((c) == '\r')) #define DEGTORAD(d) ((d) * PI / 180) #define RADTODEG(r) ((r) * 180 / PI) /* * Seeks s to next argument. * * If s is "red green blue" then return will be "green blue". */ static const char *NEXT_ARG(const char *s) { if(s == NULL) return(s); /* Seek past current arg till next blank or end of string */ while(!ISBLANK(*s) && (*s != '\0')) s++; /* Seek past spaces to next arg */ while(ISBLANK(*s)) s++; return(s); } /* * Terminates the string on the first blank character encountered. */ static void CHOP_STR_BLANK(char *s) { if(s == NULL) return; while(*s != '\0') { if(ISBLANK(*s)) { *s = '\0'; break; } else { s++; } } } /* * Return a statically allocated string indicating the * operation fetched from the pointed to fp. Return can be * an empty string if there was no op string to be found or * error. * * fp is positioned at the end of the op string which the next * fetch can be used to get its argument. If a new line character * is detected at the end of string on file, then the fp will be * repositioned at that new line character. The next reading of fp * will read that new line character. */ static char *SARParmLoadFromFileGetParmString(FILE *fp) { int c, i; #define len 80 static char rtn_str[len]; *rtn_str = '\0'; if(fp == NULL) return(rtn_str); /* Seek past spaces */ FSeekPastSpaces(fp); /* Iterate through file in order to get next parameter */ for(i = 0; i < len; i++) { c = fgetc(fp); /* End of parameter string or end of file? */ if(ISBLANK(c) || (c == EOF)) { rtn_str[i] = '\0'; break; } /* Escape sequence? */ else if(c == '\\') { c = fgetc(fp); if(c == EOF) { rtn_str[i] = '\0'; break; } if(c != '\\') c = fgetc(fp); if(c == EOF) { rtn_str[i] = '\0'; break; } } /* Newline? */ else if(ISCR(c)) { /* Newline right at the end of the op string, seek * back one character so subsequent read gets this * newline character. */ fseek(fp, -1, SEEK_CUR); rtn_str[i] = '\0'; break; } rtn_str[i] = (char)c; } #undef len return(rtn_str); } /* * Loads the value in parm_str and val_str into the given parm * array. * * The number of lines_read will be incremented. * * If filter_parm_type is not -1 then only parms matching the * specified type will be added to the given parm list. * * Returns the number of parameters loaded during this call. */ static int SARParmLoadFromFileIterate( const char *filename, void ***parm, int *total_parms, const char *parm_str, const char *val_str, int *lines_read, int filter_parm_type ) { int parms_loaded = 0; int i, parm_num; const char *cstrptr; void *p; if((parm_str == NULL) || (val_str == NULL)) return(parms_loaded); /* Increment *lines_read if a newline is found by iterating * through val_str. Note that we count this call as at least * adding one new line. */ i = *lines_read + 1; for(cstrptr = val_str; *cstrptr != '\0'; cstrptr++) { if(ISCR(*cstrptr)) i++; } *lines_read = i; /* Seek val_str past initial spaces */ while(ISBLANK(*val_str)) val_str++; /* Adds parm p to the given parm list */ #define DO_ADD_PARM \ { \ parm_num = *total_parms; \ *total_parms = parm_num + 1; \ *parm = (void **)realloc( \ *parm, (*total_parms) * sizeof(void *) \ ); \ if(*parm == NULL) \ { \ *total_parms = 0; \ return(parms_loaded); \ } \ else \ { \ (*parm)[parm_num] = p; \ parms_loaded++; \ } \ } /* Checks if filter parm type matches with the given parm type. * If the parm matches or filter_parm_type is -1 then true is returned. */ #define FILTER_CHECK(t) ( \ (filter_parm_type == (t)) || (filter_parm_type < 0) \ ) /* Begin matching the given parameter name string */ /* Version (of file format) */ if(!strcasecmp(parm_str, "version") && FILTER_CHECK(SAR_PARM_VERSION) ) { p = SARParmNew( SAR_PARM_VERSION ); sar_parm_version_struct *pv = (sar_parm_version_struct *)p; cstrptr = val_str; pv->major = ATOI(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->minor = ATOI(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->release = ATOI(cstrptr); cstrptr = NEXT_ARG(cstrptr); free(pv->copyright); pv->copyright = STRDUP(cstrptr); /* Do not chop name */ /* CHOP_STR_BLANK(pv->name); */ DO_ADD_PARM } /* Name (of file) */ else if(!strcasecmp(parm_str, "name") && FILTER_CHECK(SAR_PARM_NAME) ) { p = SARParmNew(SAR_PARM_NAME); sar_parm_name_struct *pv = (sar_parm_name_struct *)p; free(pv->name); pv->name = STRDUP(val_str); DO_ADD_PARM } /* Description (of file) */ else if((!strcasecmp(parm_str, "description") || !strcasecmp(parm_str, "desc") ) && FILTER_CHECK(SAR_PARM_DESCRIPTION) ) { p = SARParmNew(SAR_PARM_DESCRIPTION); sar_parm_description_struct *pv = (sar_parm_description_struct *)p; free(pv->description); pv->description = STRDUP(val_str); DO_ADD_PARM } /* Player model file */ else if(!strcasecmp(parm_str, "player_model_file") && FILTER_CHECK(SAR_PARM_PLAYER_MODEL_FILE) ) { p = SARParmNew(SAR_PARM_PLAYER_MODEL_FILE); sar_parm_player_model_file_struct *pv = (sar_parm_player_model_file_struct *)p; cstrptr = val_str; free(pv->file); pv->file = STRDUP(cstrptr); CHOP_STR_BLANK(pv->file); DO_ADD_PARM } /* Weather */ else if(!strcasecmp(parm_str, "weather") && FILTER_CHECK(SAR_PARM_WEATHER) ) { p = SARParmNew(SAR_PARM_WEATHER); sar_parm_weather_struct *pv = (sar_parm_weather_struct *)p; free(pv->weather_preset_name); pv->weather_preset_name = STRDUP(val_str); /* do not chop off name */ /* CHOP_STR_BLANK(pv->weather_preset_name); */ DO_ADD_PARM } /* Time of day */ else if(!strcasecmp(parm_str, "time_of_day") && FILTER_CHECK(SAR_PARM_TIME_OF_DAY) ) { int h, m, s; p = SARParmNew(SAR_PARM_TIME_OF_DAY); sar_parm_time_of_day_struct *pv = (sar_parm_time_of_day_struct *)p; cstrptr = val_str; SARParseTimeOfDay(cstrptr, &h, &m, &s); pv->tod = (float)( (h * 3600.0) + (m * 60.0) + s ); DO_ADD_PARM } /* Registered location */ else if((!strcasecmp(parm_str, "register_location") || !strcasecmp(parm_str, "reg_location") || !strcasecmp(parm_str, "reg_loc") ) && FILTER_CHECK(SAR_PARM_REGISTER_LOCATION) ) { p = SARParmNew(SAR_PARM_REGISTER_LOCATION); sar_parm_register_location_struct *pv = (sar_parm_register_location_struct *)p; /* Position (xyz) */ cstrptr = val_str; pv->pos.x = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.y = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.z = (float)SFMFeetToMeters(ATOF(cstrptr)); /* Direction */ cstrptr = NEXT_ARG(cstrptr); pv->dir.heading = (float)DEGTORAD(ATOF(cstrptr)); cstrptr = NEXT_ARG(cstrptr); pv->dir.pitch = (float)DEGTORAD(ATOF(cstrptr)); cstrptr = NEXT_ARG(cstrptr); pv->dir.bank = (float)DEGTORAD(ATOF(cstrptr)); /* Name */ cstrptr = NEXT_ARG(cstrptr); free(pv->name); pv->name = STRDUP(cstrptr); /* Do not chop name */ /* CHOP_STR_BLANK(pv->name); */ DO_ADD_PARM } /* Scene global positioning */ else if((!strcasecmp(parm_str, "scene_gps") || !strcasecmp(parm_str, "scene_global_position") ) && FILTER_CHECK(SAR_PARM_SCENE_GPS) ) { p = SARParmNew(SAR_PARM_SCENE_GPS); sar_parm_scene_gps_struct *pv = (sar_parm_scene_gps_struct *)p; /* Center offset in degrees */ cstrptr = val_str; SARParseLongitudeDMS(cstrptr, &pv->dms_x_offset); cstrptr = NEXT_ARG(cstrptr); SARParseLatitudeDMS(cstrptr, &pv->dms_y_offset); /* Planet radius in meters */ cstrptr = NEXT_ARG(cstrptr); pv->planet_radius = ATOF(cstrptr); DO_ADD_PARM } /* Scene map */ else if(!strcasecmp(parm_str, "scene_map") && FILTER_CHECK(SAR_PARM_SCENE_MAP) ) { p = SARParmNew(SAR_PARM_SCENE_MAP); sar_parm_scene_map_struct *pv = (sar_parm_scene_map_struct *)p; /* Size in meters */ cstrptr = val_str; pv->width = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->height = ATOF(cstrptr); /* Texture file */ cstrptr = NEXT_ARG(cstrptr); free(pv->file); pv->file = STRDUP(cstrptr); CHOP_STR_BLANK(pv->file); DO_ADD_PARM } /* Scene globally applied elevation */ else if(!strcasecmp(parm_str, "scene_elevation") && FILTER_CHECK(SAR_PARM_SCENE_ELEVATION) ) { p = SARParmNew(SAR_PARM_SCENE_ELEVATION); sar_parm_scene_elevation_struct *pv = (sar_parm_scene_elevation_struct *)p; /* Elevation in meters */ cstrptr = val_str; pv->elevation = (float)SFMFeetToMeters(ATOF(cstrptr)); DO_ADD_PARM } /* Scene globally applied cant angle */ else if(!strcasecmp(parm_str, "scene_cant") && FILTER_CHECK(SAR_PARM_SCENE_CANT) ) { p = SARParmNew(SAR_PARM_SCENE_CANT); sar_parm_scene_cant_struct *pv = (sar_parm_scene_cant_struct *)p; /* Angle in radians */ cstrptr = val_str; pv->cant = (float)DEGTORAD(ATOF(cstrptr)); DO_ADD_PARM } /* Scene ground base flags */ else if(!strcasecmp(parm_str, "scene_ground_flags") && FILTER_CHECK(SAR_PARM_SCENE_GROUND_FLAGS) ) { p = SARParmNew(SAR_PARM_SCENE_GROUND_FLAGS); sar_parm_scene_ground_flags_struct *pv = (sar_parm_scene_ground_flags_struct *)p; pv->flags = 0; /* Get flags */ cstrptr = val_str; while((cstrptr != NULL) ? (*cstrptr != '\0') : 0) { if(strcasepfx(cstrptr, "is_water") || strcasepfx(cstrptr, "iswater") ) pv->flags |= SAR_SCENE_BASE_FLAG_IS_WATER; cstrptr = NEXT_ARG(cstrptr); } DO_ADD_PARM } /* Scene ground tile */ else if(!strcasecmp(parm_str, "scene_ground_tile") && FILTER_CHECK(SAR_PARM_SCENE_GROUND_TILE) ) { p = SARParmNew(SAR_PARM_SCENE_GROUND_TILE); sar_parm_scene_ground_tile_struct *pv = (sar_parm_scene_ground_tile_struct *)p; /* Tile size in meters */ cstrptr = val_str; pv->tile_width = ATOI(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->tile_height = ATOI(cstrptr); /* Close range in meters */ cstrptr = NEXT_ARG(cstrptr); pv->close_range = ATOF(cstrptr); /* Far solid color */ cstrptr = NEXT_ARG(cstrptr); pv->color.r = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->color.g = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->color.b = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->color.a = ATOF(cstrptr); /* Texture name */ cstrptr = NEXT_ARG(cstrptr); free(pv->texture_name); pv->texture_name = STRDUP(cstrptr); CHOP_STR_BLANK(pv->texture_name); DO_ADD_PARM } /* Texture base directory */ else if(!strcasecmp(parm_str, "texture_base_directory") && FILTER_CHECK(SAR_PARM_TEXTURE_BASE_DIRECTORY) ) { p = SARParmNew(SAR_PARM_TEXTURE_BASE_DIRECTORY); sar_parm_texture_base_directory_struct *pv = (sar_parm_texture_base_directory_struct *)p; free(pv->directory); pv->directory = STRDUP(val_str); CHOP_STR_BLANK(pv->directory); DO_ADD_PARM } /* Texture load */ else if(!strcasecmp(parm_str, "texture_load") && FILTER_CHECK(SAR_PARM_TEXTURE_LOAD) ) { p = SARParmNew(SAR_PARM_TEXTURE_LOAD); sar_parm_texture_load_struct *pv = (sar_parm_texture_load_struct *)p; /* Name */ cstrptr = val_str; free(pv->name); pv->name = STRDUP(cstrptr); CHOP_STR_BLANK(pv->name); /* File */ cstrptr = NEXT_ARG(cstrptr); free(pv->file); pv->file = STRDUP(cstrptr); CHOP_STR_BLANK(pv->file); /* Priority */ cstrptr = NEXT_ARG(cstrptr); pv->priority = ATOF(cstrptr); DO_ADD_PARM } /* Mission scene file */ else if(!strcasecmp(parm_str, "mission_scene_file") && FILTER_CHECK(SAR_PARM_MISSION_SCENE_FILE) ) { p = SARParmNew(SAR_PARM_MISSION_SCENE_FILE); sar_parm_mission_scene_file_struct *pv = (sar_parm_mission_scene_file_struct *)p; free(pv->file); pv->file = STRDUP(val_str); DO_ADD_PARM } /* Mission create new objective */ else if(!strcasecmp(parm_str, "mission_objective_new") && FILTER_CHECK(SAR_PARM_MISSION_NEW_OBJECTIVE) ) { p = SARParmNew(SAR_PARM_MISSION_NEW_OBJECTIVE); sar_parm_mission_new_objective_struct *pv = (sar_parm_mission_new_objective_struct *)p; /* Objective type */ cstrptr = val_str; /* Arrive at objective? */ if(strcasepfx(cstrptr, "arrive")) { pv->objective_type = SAR_MISSION_OBJECTIVE_ARRIVE_AT; } /* Pick up and arrive at? */ else if(strcasepfx(cstrptr, "pick_up_arrive")) { pv->objective_type = SAR_MISSION_OBJECTIVE_PICK_UP_ARRIVE_AT; } /* Pick up? */ else if(strcasepfx(cstrptr, "pick_up")) { pv->objective_type = SAR_MISSION_OBJECTIVE_PICK_UP; } /* Unsupported mission objective type */ else { pv->objective_type = -1; fprintf( stderr, "%s: %i: %s: Warning: Unsupported objective type `%s'.\n", filename, *lines_read, parm_str, cstrptr ); } DO_ADD_PARM } /* Mission time left */ else if(!strcasecmp(parm_str, "mission_objective_time_left") && FILTER_CHECK(SAR_PARM_MISSION_TIME_LEFT) ) { p = SARParmNew(SAR_PARM_MISSION_TIME_LEFT); sar_parm_mission_time_left_struct *pv = (sar_parm_mission_time_left_struct *)p; /* Time left in seconds (note that the type is float) */ cstrptr = val_str; pv->time_left = ATOF(cstrptr); DO_ADD_PARM } /* Mission begin at */ else if(!strcasecmp(parm_str, "mission_begin_at") && FILTER_CHECK(SAR_PARM_MISSION_BEGIN_AT) ) { p = SARParmNew(SAR_PARM_MISSION_BEGIN_AT); sar_parm_mission_begin_at_struct *pv = (sar_parm_mission_begin_at_struct *)p; /* Begin at object name */ cstrptr = val_str; free(pv->name); pv->name = STRDUP(cstrptr); /* Do not chop off string */ /* CHOP_STR_BLANK(pv->name); */ DO_ADD_PARM } /* Mission begin at position */ else if(!strcasecmp(parm_str, "mission_begin_at_pos") && FILTER_CHECK(SAR_PARM_MISSION_BEGIN_AT_POS) ) { p = SARParmNew(SAR_PARM_MISSION_BEGIN_AT_POS); sar_parm_mission_begin_at_pos_struct *pv = (sar_parm_mission_begin_at_pos_struct *)p; /* Position */ cstrptr = val_str; pv->pos.x = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.y = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.z = (float)SFMFeetToMeters(ATOF(cstrptr)); /* Direction */ cstrptr = NEXT_ARG(cstrptr); pv->dir.heading = (float)DEGTORAD(ATOF(cstrptr)); cstrptr = NEXT_ARG(cstrptr); pv->dir.pitch = (float)DEGTORAD(ATOF(cstrptr)); cstrptr = NEXT_ARG(cstrptr); pv->dir.bank = (float)DEGTORAD(ATOF(cstrptr)); DO_ADD_PARM } /* Mission arrive at */ else if(!strcasecmp(parm_str, "mission_objective_arrive_at") && FILTER_CHECK(SAR_PARM_MISSION_ARRIVE_AT) ) { p = SARParmNew(SAR_PARM_MISSION_ARRIVE_AT); sar_parm_mission_arrive_at_struct *pv = (sar_parm_mission_arrive_at_struct *)p; /* Arrive at object name */ cstrptr = val_str; free(pv->name); pv->name = STRDUP(cstrptr); /* Do not chop off string */ /* CHOP_STR_BLANK(pv->name); */ DO_ADD_PARM } /* Mission message success */ else if(!strcasecmp(parm_str, "mission_objective_message_success") && FILTER_CHECK(SAR_PARM_MISSION_MESSAGE_SUCCESS) ) { p = SARParmNew(SAR_PARM_MISSION_MESSAGE_SUCCESS); sar_parm_mission_message_success_struct *pv = (sar_parm_mission_message_success_struct *)p; /* Mission success message */ cstrptr = val_str; free(pv->message); pv->message = STRDUP(cstrptr); /* Do not chop off string */ /* CHOP_STR_BLANK(pv->message); */ DO_ADD_PARM } /* Mission message fail */ else if(!strcasecmp(parm_str, "mission_objective_message_fail") && FILTER_CHECK(SAR_PARM_MISSION_MESSAGE_FAIL) ) { p = SARParmNew(SAR_PARM_MISSION_MESSAGE_FAIL); sar_parm_mission_message_fail_struct *pv = (sar_parm_mission_message_fail_struct *)p; /* Mission fail message */ cstrptr = val_str; free(pv->message); pv->message = STRDUP(cstrptr); /* Do not chop off string */ /* CHOP_STR_BLANK(pv->message); */ DO_ADD_PARM } /* Mission humans tally */ else if(!strcasecmp(parm_str, "mission_objective_humans_tally") && FILTER_CHECK(SAR_PARM_MISSION_HUMANS_TALLY) ) { p = SARParmNew(SAR_PARM_MISSION_HUMANS_TALLY); sar_parm_mission_humans_tally_struct *pv = (sar_parm_mission_humans_tally_struct *)p; /* Initial humans that need to be rescued (can be less or * equal to total_humans. */ cstrptr = val_str; pv->humans_need_rescue = ATOI(cstrptr); /* Total humans that needed to be rescued */ cstrptr = NEXT_ARG(cstrptr); pv->total_humans = ATOI(cstrptr); if(pv->humans_need_rescue < pv->total_humans) fprintf( stderr, "%s: %i: %s: Warning: humans_need_rescue `%i' is less than total_humans `%i'.\n", filename, *lines_read, parm_str, pv->humans_need_rescue, pv->total_humans ); DO_ADD_PARM } /* Mission add intercept */ else if(!strcasecmp(parm_str, "mission_add_intercept") && FILTER_CHECK(SAR_PARM_MISSION_ADD_INTERCEPT) ) { p = SARParmNew(SAR_PARM_MISSION_ADD_INTERCEPT); sar_parm_mission_add_intercept_struct *pv = (sar_parm_mission_add_intercept_struct *)p; /* Reference code */ cstrptr = val_str; pv->ref_code = ATOI(cstrptr); /* Handle rest by reference code to determine how many * arguments. */ switch(pv->ref_code) { /* Arrive or begin at location: * * */ case 3: case 2: /* Radius */ cstrptr = NEXT_ARG(cstrptr); pv->radius = ATOF(cstrptr); /* Urgency */ cstrptr = NEXT_ARG(cstrptr); pv->urgency = ATOF(cstrptr); break; /* Standard intercept way point: * * */ case 0: /* Position */ cstrptr = NEXT_ARG(cstrptr); pv->pos.x = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.y = ATOF(cstrptr); cstrptr = NEXT_ARG(cstrptr); pv->pos.z = ATOF(cstrptr); /* In meters */ /* Radius */ cstrptr = NEXT_ARG(cstrptr); pv->radius = ATOF(cstrptr); /* Urgency */ cstrptr = NEXT_ARG(cstrptr); pv->urgency = ATOF(cstrptr); break; default: fprintf( stderr, "%s: %i: %s: Warning: Unsupported intercept code `%s'.\n", filename, *lines_read, parm_str, cstrptr ); break; } /* Last argument is the intercept point's name */ cstrptr = NEXT_ARG(cstrptr); free(pv->name); pv->name = STRDUP(cstrptr); /* Do not chop off string */ /* CHOP_STR_BLANK(pv->name); */ DO_ADD_PARM } /* New object */ else if((!strcasecmp(parm_str, "create_object") || !strcasecmp(parm_str, "new_object") || !strcasecmp(parm_str, "add_object") ) && FILTER_CHECK(SAR_PARM_NEW_OBJECT) ) { p = SARParmNew(SAR_PARM_NEW_OBJECT); sar_parm_new_object_struct *pv = (sar_parm_new_object_struct *)p; /* First int is object type */ cstrptr = val_str; pv->object_type = ATOI(cstrptr); DO_ADD_PARM } /* New helipad */ else if((!strcasecmp(parm_str, "create_helipad") || !strcasecmp(parm_str, "new_helipad") || !strcasecmp(parm_str, "add_helipad") ) && FILTER_CHECK(SAR_PARM_NEW_HELIPAD) ) { p = SARParmNew(SAR_PARM_NEW_HELIPAD); sar_parm_new_helipad_struct *pv = (sar_parm_new_helipad_struct *)p; /* Begin parsing line, format: * *