searchandrescue_1.5.0/0000755000175000017500000000000012026716252013745 5ustar jessejessesearchandrescue_1.5.0/LICENSE0000644000175000017500000003611007263212332014750 0ustar jessejesse GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS searchandrescue_1.5.0/copyright0000644000175000017500000000113011344253463015675 0ustar jessejesseThis 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.5.0/pconf/0000755000175000017500000000000011441747257015063 5ustar jessejessesearchandrescue_1.5.0/pconf/pconf0000755000175000017500000012441611344252667016124 0ustar jessejesseELF44 ($!444444  T  HHHDDQtdRtd  /lib/ld-linux.so.2GNUGNUصŁd     #")K90 KYCf)`{8Su>n ` __gmon_start__libc.so.6_IO_stdin_usedfflushsprintffopenputsputcharreallocfgetccallocfseektoupperstdoutfputcfclosemallocgetenvstderrfwriteatoifprintf__libc_start_mainfree__xstatGLIBC_2.1GLIBC_2.0ii ii `            $  (  ,  0  4 8 < @ D H L P T US[Йt>kX[5%% h% h% h% h% h % h(% h0% h8p% h@`%$ hHP%( hP@%, hX0%0 h` %4 hh%8 hp%< hx%@ h%D h%H h%L h%P h%T h1^PTRh h0QVhUS= u? 9s  9r []Ít&'Utt $ÐU(}t]E$g`EE>E< t E< u&EEEEEEuEEuU(}EnE@UЋE}LEE@UЋE}tuE@$^E@$]EPE@T$$bEPE@T$$bE@ $]E@$$]E$]EE@;E^E@$w]E@E@E$V]E@$H]E@$:]E@ $,]E@$]E@ $]E@$$]E@($\E$\EE@ ;EE@$\E@E@ E$\E@$\EPE@T$$IaEPE@T$$1aEP$E@ T$$aEP,E@(T$$aEP4E@0T$$`E@8$\E@<$\E@@$[E@D$[E@H$[E@L$[E@P$[E$[U(}tr} toE.EUЋ$ EUEE ;EȋEtE$B[EE US}t} u MD$ E $$`E}u'#` M L$T$$ EEEEEEED$ =D$#ED$E$aE}uFE$_EEEEEEEhEED$5E$\uE$_bD$=E$\uE$_;D$DE$f\uE$m_D$PE$?\E$_EЋEЉ$EEEEEEE@ EEPEP E@ E@T$$Q‹EPE@uE@ E+E@UD$T$)E܋E܉}t E܋UЉEЉ$XD$YE$:[E$^E̋Ẻ$EE}u)l` ML$ M L$T$$bE܋@ EEPE܉P E܋@ E܋@T$$9‹E܉PE܋@uE@ EE+E܋@UD$,$ E؋E؉}tẺ$XU؉Ẻ$WD$E$Zt2D$E$ZtD$E$YE$]EȋEȉ$F}u)` ML$ M L$T$$ E؋@EEPE؉PE؋@E؋@T$$‹E؉PE؋@uE@EE+E؋@UD$($EԋEԉ}tEȉ$EWUԉBEȉ$BV~D$'E$XE${\EċEĉ$1}t!Eԋ@$UEĉ$VUԉB|}t!E؋@$UEĉ$VU؉BU}t!E܋@$UEĉ$VU܉B.E@t$4` ML$ M L$T$$Eĉ$[UD$`E$WtD$sE$Wu~E$[EE$7}t!E؋@$TE$UU؉B.E@t$4` ML$ M L$T$$E$TD$E$BWtD$E$+Wu~E$ZEE$}t!E؋@ $OTE$6UU؉B .E@t$4` ML$ M L$T$$:E$T?D$E$VE$QUԉB Eԋ tD` ML$T$$KE$PPD$E$RtD$E$RuuE$:VEE$}tFEԋ@$$OE$PUԉB$Eԋ t` ML$T$$E$qO D$E$RtD$E$QuNE$UEE$M}tE؋@$OE$OU؉BE$N1 D$E$QtED$E$qQt.D$#E$ZQtD$2E$CQuNE$TEE$}tE؋@ $gNE$NOU؉B E$KN D$@E$PtD$LE$PuNE$qTEE$'}tE؋@$$ME$NU؉B$E$M D$WE$bPtED$gE$KPt.D$vE$4PtD$E$PuNE$SEE$}}tE؋@($AME$(NU؉B(E$%Ma D$E$Ot.D$E$OtD$E$OuNE$4SEE$}tE܍HE܍PED$L$$PE$L D$E$%OtD$E$OuNE$REE$n}tE܍HE܍PED$L$$*PE$LR D$ E$Nt.D$,E$NtD$EE${NuNE$%REE$}tE܍H$E܍P ED$L$$OE$K D$[E$Nt.D$uE$MtD$E$MuNE$QEE$H}tE܍H,E܍P(ED$L$$OE$J, D$E$MtD$E$lMuZE$Q||$}t"E܍H4E܍P0|D$L$$N|$hJD$E$LtD$E$LuZE$Pxx$>}t"E܋@8$Jx$JU܉B8x$ID$E$sLtD$E$\LuZE$Ptt$}t"E܋@<$zIt$^JU܉BE@t$(` ML$ M L$T$$E$G,'[]U(}t} u D$ E $FE}u E$GE}tE@D$MAE$4BUBDE$1AE$GEE$AE$qGE}tE@H$@E$AUBHE$@E$,FEUH}} E@(EE@,EE@0E}uEID$RE$EE}u"T` ML$T$$r7hUT$$)D$ E$JEE}tED$ ED$ED$E$i}~ $ xEEE;Ev}u}tYUT$$U(}u} ^EE} ~ EED$pE$4E}uE$4} UpD$`D$\D$XD$TD$PD$LD$HD$DD$@D$D$8|$8uFD$H$$D$HD$D$$D$DD$@$$D$@$y)D$$|$$u$~)D$$|$$u$g)D$$|$$tD$$$LT$8BD$8T$`D$8T$\PD$8T$XPD$8T$TP D$8T$PPD$8T$LPD$HD$D$8$D$h|$htZD$8$D$8D$H$#D$HD$D$#D$DD$@$#D$@|$<D$8P D$8@D$L$E@u }CE$ EEEUT$ UT$D$E $E} Et! UT$$o $E%=@uaEtQ D$ D$E$* $! D$D$E$$ YEE%= uaEtQ D$ D$E$ $豩 D$D$E$$ EE%=`uaEtQ D$ D$E$J $A D$D$E$!$ yEE%=uaEtQ D$ D$E$ $Ѩ D$D$E$$  EE%=uaEtQ D$ D$E$j $a D$D$E$A$) 虨EE%=},E@;EE@UЋE܃}EE܉D$E$W~YEtD D$ D$E$$2  D$D$E$tE#EtD D$D$E$C$6 蛧 D$D$E$E@` D$D$E$` ¸> T$ D$D$$` D$D$E$H ` ML$ M܉L$T$$车` D$D$E$m` ¸h T$ D$D$$iEE D$ D$E$$2 g D$D$E$WEtD D$ D$E$$2  D$D$E$E}EE@` D$D$E$Q` ¸> T$ D$D$$M` D$!D$E$ p ` ML$T$$$` D$D$E$` ¸h T$ D$D$$ФEEE@;EE$E}UXEE}t} uEBE!E @UЋE}E @ ~EkdU R щEE@E@EEfE@UЋE܃}tHE܋@ u>E P ET$UT$D$ E܉D$E D$E$uEEE@;E}E@tgE T$$, D$ D$E$ $ D$D$E$$ ;E@E@ $豢 D$ D$E$ $舢 D$D$E$hE T$$V D$!D$E$6$- D$D$E$ $ eE@E@EEzE@UЋEЃ}t\E@u}bEЋ@ uBE P ET$UT$D$ EЉD$E D$E$u EEEE@;Ew}(` D$D$E$!` ¸> T$ D$D$$` D$D$E$E` L$T$$` D$D$E$` ¸h T$ D$D$$螠E@u E@E@t\Et:E@t3` ¸XT$ D$6D$$E EE @ ;EEÐU}tE$腟UE}uEEEuEU}uEE< tE< tE$YuQD$E$t3E$讞TuE<0tU(E}uEYE$EE$EEE}uE)EEEEEuEEU}tE u(EE 8uEEEuݸ]U}EEEEE< tEE< t}~VEEEEEUUEEEEuڋEE}~EE$E$E}~EEEE'EE< t EE< uEEm}yUS}t} u@jE$覜ËE $蓜9t;EE Et E uEE 8u[]U}t} uBE u(1EE 8tEE E uԸ]US}t} uZE u@IE$豛ËE $螛9tEE E u[]U(}t } t}u E y E E$E}uqE EEPE E ET$$贚‹EEuE E$TEUEEU(}t6EEE$ EE;E |E$U}u E$U}t} uE D$E$聚U}tE$XU}u E$TU} uE D$E$荚U(}t8E$E}\uE$E } t} t}uU(}tGE$OE}t)} t} tD$D$E$aU8EE}uEE$E}uEEEEED$E$~E}EEEE‹E}t } t} uEt}\uUE$qE}uR} t} u E‹E}\u E‹E&E$/EOE$E<7EU8UEUEEE}uE $^} t E $`EE$ Enables the specified . --disable= Disables the specified . --= Override with new , example: --prefix=/usr/local/ Where [options] can be any of the following: --list[=] Show descriptions and features of each platform (or just a specific platform if is specified). --listall[=] Show descriptions, features, dependancies, and all other details of each platform (or just a specific platform if is specified). --v Prints extra verbose messages (also displays post configuration report). --interactive Use interactive mode when needed. --no-warnings Do not print warning messages. --no-colors Disable ANSI color. --force Ignore errors when possible. --ignore-environments Do not use any environment variable values. --help Prints (this) help screen and exits. --version Prints version information and exits. Examples: ./configure --listall ./configure Linux --prefix=/usr/local/ ./configure UNIX -v --prefix=/usr --CFLAGS="-O2 -g -Wall" Platform: Description: %s PREFIX: %s CFLAGS: %s INC_DIRS: %s LIBS: %s LIB_DIRS: %s CC: %s CPP: %s Feature%s (DisabledEnabledUndefined)Not Checked) To Enable: --enable="%s" Preferred) To Disable: --disable="%s" Required Description: %s URL Home Page: %s URL Download: %s Depends On: %s No platforms defined.Available platforms: No such platform "%s" rb--h-h-?/?--ver-ver%s Version %s 0.0.1Compiler Configurator-v--no_warnings--no_warn--no-warnings--no-warn-no_warnings-no_warn-no-warnings-no-warn--nowarnings-nowarn--interactive-interactive--i-i--force-force--no-colors--no-colours--no_colors--no_colours--no-color--no-colour--no_color--no_colour-no-colors-no-colours-no_colors-no_colours-no-color-no-colour-no_color-no_colour--nocolors--nocolours--nocolor--nocolour-nocolors-nocolours-nocolor-nocolour--ignore_environments-ignore_environments--ignore-environments-ignore-environments--ignoreenvironments-ignoreenvironments%s: Cannot open platforms configuration file. This file is used to configure generation of the output Makefile used in compiling the program source, it should be specified as the first argument. If you cannot locate the platforms configuration file, notify the vendor that this file is missing. You must specify a supported platform to configure for.--list_a-list_a--lista-lista--list-listCOLUMNSSCREEN_WIDTHSCREENWIDTH For more details and features available on each platform, specify the --listall argument. To configure for a particular platform, just specify that platform's name.%s: No such platform. Use argument --listall to list available platforms. %s Configuring for platform `%s'... *** dependenciesdependency%i failed %s ignored (because --force used)! *** %i failed %s!Configuration Review: Platform configuration completed!PREFIXCFLAGSINC_DIRSLIBSLIB_DIRSCCCPPLD_LIBRARY_PATH-LAdding platform's library path: %s enablewith%s: No such feature to enable. Error enabling this feature. --%s: Argument must have a value separated by a '='. disablewithoutwith-outwith_outThis feature is not allowed to be disabled. No such feature to disable. Error encountered while attempting to disable feature. --%s: Argument must have a value separated by a '=' or '-' character. PlatformPREFIXPlatformCFLAGSPlatformINC_DIRSINCDIRSPlatformINCDIRSINC_DIRPlatformINC_DIRINCDIRPlatformINCDIRPlatformLIBSPlatformLIB_DIRSLIBDIRSPlatformLIBDIRSLIB_DIRPlatformLIB_DIRLIBDIRPlatformLIBDIRrbPConfDependMatchFile(): Internal error, dependency is not looking for a file. %s%c%s%s%sF2ZZFeature: %s (%i of %i) Dependency: %s... Checking Dependency: %s... Scanning: %s... OK (Directory)(Character Device)(Block Device)(FIFO Pipe)(Socket) OK Failed *** Could not find `%s' in file %s! *** Object `%s' not found in defined platform paths! Preferred feature `%s' detected and enabled. Preferred (not required) feature `%s' not detected and disabledCould not find all dependencies for required feature `%s'!*** Force enabled, continuing dependency check... *** ON  o@ l hPo oo ^n~Άކ.>N^n~GCC: (Ubuntu 4.4.1-4ubuntu8) 4.4.1GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"!bu_IO_stdin_used^../sysdeps/i386/elf/start.S/build/buildd/eglibc-2.10.1/csuGNU AS 2.203}[o b]q?intXxIO%% $ > $ > $ > 4: ; I?  &IW2 ../sysdeps/i386/elfstart.S3!4=%" YZ!"\[# init.c/build/buildd/eglibc-2.10.1/csushort unsigned intGNU C 4.4.1short int_IO_stdin_usedlong long unsigned intunsigned charinit.clong long int.symtab.strtab.shstrtab.interp.note.ABI-tag.note.gnu.build-id.gnu.hash.dynsym.dynstr.gnu.version.gnu.version_r.rel.dyn.rel.plt.init.text.fini.rodata.eh_frame.ctors.dtors.jcr.dynamic.got.got.plt.data.bss.comment.debug_aranges.debug_pubnames.debug_info.debug_abbrev.debug_line.debug_str44#HH 1hh$HDo@@,N llV  ^o4ko  0z PP hh 0HHp0#C 4Hh@l   P h  H   X `   !/<R a oP{tl= ^9-AyRYhYlk   X  #.A Q>sX_{  8KhDvL{22"X  Ul|-i4` 0E=N%vi\ v'0ZZT, );N` Zl\ sA  ZVz  M` a h init.ccrtstuff.c__CTOR_LIST____DTOR_LIST____JCR_LIST____do_global_dtors_auxcompleted.6990dtor_idx.6992frame_dummy__CTOR_END____FRAME_END____JCR_END____do_global_ctors_auxfio.cPConfLoadPlatformsSanitizeLinemain.cPConfMatchPlatformByNamePConfFreeCorePConfPrintHelpPConfPrintPlatformPConfPrintPlatformsPConfPrereqCheckproc.cPConfEnableFeaturePConfDisableFeaturePConfScanFileStringPConfDependMatchFilePConfDependCheckutils.c_GLOBAL_OFFSET_TABLE___init_array_end__init_array_start_DYNAMICdata_startPConfFreePlatformsSTRCASECMPsprintf@@GLIBC_2.0__libc_csu_finiSTRDUP_startPConfGenerateOutputMakefileSTRSTRIP__xstat@@GLIBC_2.0__gmon_start___Jv_RegisterClasses_fp_hwrealloc@@GLIBC_2.0STRISYESgetenv@@GLIBC_2.0_finicalloc@@GLIBC_2.0putchar@@GLIBC_2.0PConfLoadThisPlatformFromFiletoupper@@GLIBC_2.0__libc_start_main@@GLIBC_2.0PConfSetColorFREE__statstat_IO_stdin_usedfree@@GLIBC_2.0__data_startfflush@@GLIBC_2.0FGETLINEfseek@@GLIBC_2.0STRLISTAPPENDPConfCheckDependsfclose@@GLIBC_2.1FOPENSTRLENstderr@@GLIBC_2.0STRFREEARRAYfopen@@GLIBC_2.1PConfLoadPlatformsFromFile__dso_handlefgetc@@GLIBC_2.0FPUTC__DTOR_END____libc_csu_initSTRPFXprintf@@GLIBC_2.0FSEEKNEXTPARAMETERatoi@@GLIBC_2.0PConfMatchFeatureByNamePConfApplyArgsToPlatformfwrite@@GLIBC_2.0PConfFreePlatformfprintf@@GLIBC_2.0__bss_startmalloc@@GLIBC_2.0GETENVfputc@@GLIBC_2.0STRCHR_endstdout@@GLIBC_2.0puts@@GLIBC_2.0FSEEKPASTSPACESSTRCASEPFXFGETCFSEEKNEXTLINE_edataPConfPrintHR__i686.get_pc_thunk.bxFCLOSEmain_initsearchandrescue_1.5.0/pconf/Makefile0000644000175000017500000000020207303153731016503 0ustar jessejesseCC = cc BIN = pconf $(BIN): $(CC) fio.c main.c proc.c utils.c -o $(BIN) -Wall all: $(BIN) clean: rm -f *.o a.out core $(BIN) searchandrescue_1.5.0/pconf/makefile_prepend.ini0000644000175000017500000000003507303153735021046 0ustar jessejesse# Prepend stuff goes here! # searchandrescue_1.5.0/pconf/main.c0000644000175000017500000010067107330130340016135 0ustar jessejesse#include "pconf.h" void PConfSetColor(pconf_core_struct *core_ptr, FILE *stream, int color_code); static platform_struct *PConfMatchPlatformByName( platform_struct **platform, int total_platforms, const char *name, int *n ); feature_struct *PConfMatchFeatureByName( platform_struct *platform_ptr, const char *name, int *n ); static void PConfFreeCore(pconf_core_struct *core_ptr); void PConfPrintHR(pconf_core_struct *core_ptr); static void PConfPrintHelp(const char *prog_name); static void PConfPrintPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int print_level, int print_for_review ); static void PConfPrintPlatforms( pconf_core_struct *core_ptr, platform_struct **platform, int total_platforms, const char *specific_platform, int print_level, int print_for_review ); static int PConfPrereqCheck( char *platforms_ini, int argc, char **argv ); /* * Sets the stream for ansi color, color_code must be one of * PCONF_COLOR_*. */ void PConfSetColor(pconf_core_struct *core_ptr, FILE *stream, int color_code) { if(stream == NULL) return; if(core_ptr != NULL) { if(!core_ptr->colors) return; } if(color_code == PCONF_COLOR_DEFAULT) fprintf(stream, "\033[0;39m"); else if(color_code == PCONF_COLOR_SELECTABLE) fprintf(stream, "\033[4;34m"); else if(color_code == PCONF_COLOR_HEADING) fprintf(stream, "\033[1;m"); /* fprintf(stream, "\033[1;39m"); */ else fprintf(stream, "\033[1;%im", color_code); return; } /* * Returns the platform matching the specified name or NULL on failed * match. */ static platform_struct *PConfMatchPlatformByName( platform_struct **platform, int total_platforms, const char *name, int *n ) { int i; platform_struct *platform_ptr; if(n != NULL) (*n) = -1; if((platform == NULL) || (total_platforms < 1) || (name == NULL)) return(NULL); for(i = 0; i < total_platforms; i++) { platform_ptr = platform[i]; if(platform_ptr == NULL) continue; if(platform_ptr->name == NULL) continue; if(!STRCASECMP(platform_ptr->name, name)) { if(n != NULL) (*n) = i; return(platform_ptr); } } return(NULL); } /* * Returns the feature matching the specified name or NULL on failed * match. */ feature_struct *PConfMatchFeatureByName( platform_struct *platform_ptr, const char *name, int *n ) { int i; feature_struct *feature_ptr; if(n != NULL) (*n) = -1; if((platform_ptr == NULL) || (name == NULL)) return(NULL); for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; if(feature_ptr->name == NULL) continue; if(!STRCASECMP(feature_ptr->name, name)) { if(n != NULL) (*n) = i; return(feature_ptr); } } return(NULL); } /* * Deallocates the core structure and all its allocated resources. */ static void PConfFreeCore(pconf_core_struct *core_ptr) { char **s; #define DO_FREE_STRING \ { \ if((*s) != NULL) \ { \ FREE(*s); \ (*s) = NULL; \ } \ } if(core_ptr == NULL) return; PConfFreePlatforms( &core_ptr->platform, &core_ptr->total_platforms ); PConfFreePlatform(core_ptr->selected_platform); core_ptr->selected_platform = NULL; s = &core_ptr->makefile_output; DO_FREE_STRING s = &core_ptr->makefile_input_prepend; DO_FREE_STRING s = &core_ptr->makefile_input_append; DO_FREE_STRING s = &core_ptr->message_configure_startup; DO_FREE_STRING s = &core_ptr->message_platform_unsupported; DO_FREE_STRING s = &core_ptr->message_depend_failed; DO_FREE_STRING s = &core_ptr->message_success; DO_FREE_STRING s = &core_ptr->os_name; DO_FREE_STRING s = &core_ptr->machine_name; DO_FREE_STRING FREE(core_ptr); core_ptr = NULL; #undef DO_FREE_STRING return; } /* * Prints horizontal rule. */ void PConfPrintHR(pconf_core_struct *core_ptr) { int i, len = 80; if(core_ptr->screen_width > 0) len = core_ptr->screen_width; for(i = 0; i < len; i++) FPUTC('-', stdout); FPUTC('\n', stdout); return; } /* * Prints help for this program as the name specified by prog_name. * * Note that we do not show the need for the first argument since we * are printing the usage designed to be shown when called from the * configure script. */ static void PConfPrintHelp(const char *prog_name) { if(prog_name == NULL) prog_name = "pconf"; printf( "Usage: ./configure [platform] [modifiers] [options]\n" ); printf( " ./configure [options]\n" ); printf( "\n\ Where [platform] specifies the name of the platform to configure for (use\n\ the --listall argument to see a complete list of supported platforms).\n\ \n\ Where [modifiers] can be any of the following modifications of features\n\ or parameters (use the --listall argument to see a list of features\n\ and parameters of each platform):\n\ \n\ --enable= Enables the specified .\n\ --disable= Disables the specified .\n\ --= Override with new ,\n\ example: --prefix=/usr/local/\n\ \n\ Where [options] can be any of the following:\n\ \n\ --list[=] Show descriptions and features of each\n\ platform (or just a specific platform if\n\ is specified).\n\ --listall[=] Show descriptions, features, dependancies,\n\ and all other details of each platform\n\ (or just a specific platform if \n\ is specified).\n\ --v Prints extra verbose messages (also displays\n\ post configuration report).\n\ --interactive Use interactive mode when needed.\n\ --no-warnings Do not print warning messages.\n\ --no-colors Disable ANSI color.\n\ --force Ignore errors when possible.\n\ --ignore-environments Do not use any environment variable values.\n\ --help Prints (this) help screen and exits.\n\ --version Prints version information and exits.\n\ \n\ Examples:\n\ \n\ ./configure --listall\n\ \n\ ./configure Linux --prefix=/usr/local/\n\ \n\ ./configure UNIX -v --prefix=/usr --CFLAGS=\"-O2 -g -Wall\"\n\ \n" ); return; } /* * Prints the given platform. * * The given print_level determines how much info to print * out: * * 0 Print just platform names (if any). * 1 Print platform names, desc, and available features. * 2 Print platform names, desc, features, and their * dependancies. * 3 Print everything including global search paths and other * misc info. */ static void PConfPrintPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int print_level, int print_for_review ) { int n, j; feature_struct *feature_ptr; depend_struct *depend_ptr; if(platform_ptr == NULL) return; #define PLATFORMS_INDENT " " /* Print platform name? */ if(print_level >= 0) { if(print_level >= 1) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_HEADING); printf("Platform"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(": "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SELECTABLE); printf("%s\n", platform_ptr->name); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); } else { printf("%s\n", platform_ptr->name ); } /* Description (if any). */ if((platform_ptr->description != NULL) && (print_level >= 1) ) { printf( PLATFORMS_INDENT "Description: %s\n", platform_ptr->description ); } /* PREFIX (if any). */ if((platform_ptr->prefix != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "PREFIX: %s\n", platform_ptr->prefix ); } /* CFLAGS (if any). */ if((platform_ptr->cflags != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "CFLAGS: %s\n", platform_ptr->cflags ); } /* INC_DIRS (if any). */ if((platform_ptr->inc_dirs != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "INC_DIRS: %s\n", platform_ptr->inc_dirs ); } /* LIBS (if any). */ if((platform_ptr->libs != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "LIBS: %s\n", platform_ptr->libs ); } /* LIB_DIRS (if any). */ if((platform_ptr->lib_dirs != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "LIB_DIRS: %s\n", platform_ptr->lib_dirs ); } /* CC (if any). */ if((platform_ptr->cc != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "CC: %s\n", platform_ptr->cc ); } /* CPP (if any). */ if((platform_ptr->cpp != NULL) && (print_level >= 3) ) { printf( PLATFORMS_INDENT "CPP: %s\n", platform_ptr->cpp ); } } /* Print features on this platform? */ if(print_level >= 1) { #define FEATURES_INDENT " " for(n = 0; n < platform_ptr->total_features; n++) { feature_ptr = platform_ptr->feature[n]; if(feature_ptr == NULL) continue; if(feature_ptr->name != NULL) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_HEADING); printf(PLATFORMS_INDENT "Feature"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(": "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SELECTABLE); printf("%s", feature_ptr->name); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); /* Do not print newline after feature name, the must have * value will be added after it. */ } /* Print must exist in terms of printing for review. */ if(print_for_review) { /* We're printing for review, meaning configuration has * already completed. We should print its enabled/disabled * state. */ printf(" ("); switch(feature_ptr->must_exist) { case PCONF_MUST_EXIST_NO: /* Disabled. */ PConfSetColor(core_ptr, stdout, PCONF_COLOR_WARNING); printf("Disabled"); break; case PCONF_MUST_EXIST_YES: /* Enabled. */ PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS); printf("Enabled"); break; default: /* No set properly. */ PConfSetColor(core_ptr, stdout, PCONF_COLOR_FAILURE); printf("Undefined"); break; } PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(")\n"); } else { printf(" ("); switch(feature_ptr->must_exist) { case PCONF_MUST_EXIST_NO: PConfSetColor(core_ptr, stdout, PCONF_COLOR_FAILURE); printf("Not Checked"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(") To Enable: --enable=\"%s\"\n", feature_ptr->name ); break; case PCONF_MUST_EXIST_PREFERRED: PConfSetColor(core_ptr, stdout, PCONF_COLOR_WARNING); printf("Preferred"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(") To Disable: --disable=\"%s\"\n", feature_ptr->name ); break; case PCONF_MUST_EXIST_YES: PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS); printf("Required"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf(")\n"); break; } } /* Print feature description. */ if((print_level >= 2) && (feature_ptr->description != NULL)) { printf( FEATURES_INDENT "Description: %s\n", feature_ptr->description ); } /* Print feature home page url. */ if((print_level >= 3) && (feature_ptr->url_homepage != NULL)) { printf( FEATURES_INDENT "URL Home Page: %s\n", feature_ptr->url_homepage ); } /* Print feature download url. */ if((print_level >= 3) && (feature_ptr->url_download != NULL)) { printf( FEATURES_INDENT "URL Download: %s\n", feature_ptr->url_download ); } /* Print library dependancies for this feature? */ if(print_level >= 2) { #define DEPEND_INDENT " " if(feature_ptr->total_depends > 0) printf( FEATURES_INDENT "Depends On:\n" ); for(j = 0; j < feature_ptr->total_depends; j++) { depend_ptr = feature_ptr->depend[j]; if(depend_ptr == NULL) continue; if(depend_ptr->name != NULL) printf( DEPEND_INDENT "%s\n", depend_ptr->name ); } #undef DEPEND_INDENT } } #undef FEATURES_INDENT } return; } /* * Prints list of platforms. * * If no platforms exist, then "No platforms defined." will be * printed. * * The given print_level determines how much info to print * out: * * 0 Print just platform names (if any). * 1 Print platform names, desc, and available features. * 2 Print platform names, desc, features, and their * dependancies. * 3 Print everything including global search paths and other * misc info. */ static void PConfPrintPlatforms( pconf_core_struct *core_ptr, platform_struct **platform, int total_platforms, const char *specific_platform, int print_level, int print_for_review ) { int i; platform_struct *platform_ptr; int platforms_printed = 0; /* No platforms defined? */ if((platform == NULL) || (total_platforms < 1)) { printf( "No platforms defined.\n" ); return; } /* Not printing for a specific platform? */ if((specific_platform == NULL) && (total_platforms > 0)) printf("Available platforms:\n\n"); /* Itterate through all platforms. */ for(i = 0; i < total_platforms; i++) { platform_ptr = platform[i]; if(platform_ptr == NULL) continue; /* No name implies skip this platform. */ if(platform_ptr->name == NULL) continue; /* Printing for specific platform? */ if(specific_platform != NULL) { /* If names don't match then skip. */ if(STRCASECMP(specific_platform, platform_ptr->name)) continue; } /* Print this platform. */ PConfPrintPlatform( core_ptr, platform_ptr, print_level, print_for_review ); /* Print separator if printing above level 0. */ if(print_level > 0) printf("\n"); /* Increment platforms printed counter. */ platforms_printed++; #undef PLATFORMS_INDENT } /* No platforms printed? */ if(platforms_printed == 0) { if(specific_platform != NULL) printf("No such platform \"%s\"\n", specific_platform); } return; } /* Checks if required arguments have been recieved, returns non-zero * if there is something missing. * * Return values are as follows: * * 0 Success * -1 Missing platforms_ini or cannot open it * -2 Insufficient info, suggest print help * -3 Missing platform name argument, suggest print help */ static int PConfPrereqCheck( char *platforms_ini, int argc, char **argv ) { FILE *fp; /* No platforms.ini file? */ if(platforms_ini == NULL) { /* Better have two arguments atleast then. */ if(argc < 2) return(-2); else platforms_ini = argv[1]; } else { /* Platforms.ini file given, but check if command line * specifies alternate one. */ if(argc > 1) platforms_ini = argv[1]; } /* Check if we can open the platforms.ini file. */ fp = FOPEN(platforms_ini, "rb"); if(fp == NULL) { return(-1); } else { FCLOSE(fp); } /* Did we get a third argument, the platform? */ if(argc < 3) return(-3); /* All checks passed. */ return(0); } /* * Return codes: * * 0 Success * 1 Invalid value * 2 Missing or unspecified resource * 3 System error * 4 User info (ie help, version, or list platforms) */ int main(int argc, char *argv[]) { int i, status; const char *arg_ptr; int verbose = 0; int warnings = 1; int colors = 1; int interactive = 0; int force = 0; int ignore_environments = 0; char *platforms_ini = NULL; char *platform_name = NULL; char *specific_platform = NULL; int print_platforms_level = -1; pconf_core_struct *core_ptr; int selected_platform_num; platform_struct *selected_platform; #define DO_FREE_LOCALS \ { \ FREE(platforms_ini); \ platforms_ini = NULL; \ \ FREE(platform_name); \ platform_name = NULL; \ \ FREE(specific_platform); \ specific_platform = NULL; \ } /* Parse independent arguments (ie help and version). */ for(i = 1; i < argc; i++) { arg_ptr = (const char *)argv[i]; if(arg_ptr == NULL) continue; /* Help. */ if(STRCASEPFX(arg_ptr, "--h") || STRCASEPFX(arg_ptr, "-h") || !STRCASECMP(arg_ptr, "-?") || !STRCASECMP(arg_ptr, "/?") ) { PConfPrintHelp((argc > 0) ? argv[0] : NULL); DO_FREE_LOCALS return(4); } /* Version. */ else if(STRCASEPFX(arg_ptr, "--ver") || STRCASEPFX(arg_ptr, "-ver") ) { printf( "%s Version %s\n", PROG_NAME, PROG_VERSION ); DO_FREE_LOCALS return(4); } /* Verbose. */ else if(!STRCASECMP(arg_ptr, "-v")) { verbose = 1; } /* No warnings. */ else if(!STRCASECMP(arg_ptr, "--no_warnings") || !STRCASECMP(arg_ptr, "--no_warn") || !STRCASECMP(arg_ptr, "--no-warnings") || !STRCASECMP(arg_ptr, "--no-warn") || !STRCASECMP(arg_ptr, "-no_warnings") || !STRCASECMP(arg_ptr, "-no_warn") || !STRCASECMP(arg_ptr, "-no-warnings") || !STRCASECMP(arg_ptr, "-no-warn") || !STRCASECMP(arg_ptr, "--nowarnings") || !STRCASECMP(arg_ptr, "-nowarn") ) { warnings = 0; } /* Interactive. */ else if(!STRCASECMP(arg_ptr, "--interactive") || !STRCASECMP(arg_ptr, "-interactive") || !STRCASECMP(arg_ptr, "--i") || !STRCASECMP(arg_ptr, "-i") ) { interactive = 1; } /* Force. */ else if(!STRCASECMP(arg_ptr, "--force") || !STRCASECMP(arg_ptr, "-force") ) { force = 1; } /* No colors. */ else if(!STRCASECMP(arg_ptr, "--no-colors") || !STRCASECMP(arg_ptr, "--no-colours") || !STRCASECMP(arg_ptr, "--no_colors") || !STRCASECMP(arg_ptr, "--no_colours") || !STRCASECMP(arg_ptr, "--no-color") || !STRCASECMP(arg_ptr, "--no-colour") || !STRCASECMP(arg_ptr, "--no_color") || !STRCASECMP(arg_ptr, "--no_colour") || !STRCASECMP(arg_ptr, "-no-colors") || !STRCASECMP(arg_ptr, "-no-colours") || !STRCASECMP(arg_ptr, "-no_colors") || !STRCASECMP(arg_ptr, "-no_colours") || !STRCASECMP(arg_ptr, "-no-color") || !STRCASECMP(arg_ptr, "-no-colour") || !STRCASECMP(arg_ptr, "-no_color") || !STRCASECMP(arg_ptr, "-no_colour") || !STRCASECMP(arg_ptr, "--nocolors") || !STRCASECMP(arg_ptr, "--nocolours") || !STRCASECMP(arg_ptr, "--nocolor") || !STRCASECMP(arg_ptr, "--nocolour") || !STRCASECMP(arg_ptr, "-nocolors") || !STRCASECMP(arg_ptr, "-nocolours") || !STRCASECMP(arg_ptr, "-nocolor") || !STRCASECMP(arg_ptr, "-nocolour") ) { colors = 0; } /* Ignore environment variables. */ else if(!STRCASECMP(arg_ptr, "--ignore_environments") || !STRCASECMP(arg_ptr, "-ignore_environments") || !STRCASECMP(arg_ptr, "--ignore-environments") || !STRCASECMP(arg_ptr, "-ignore-environments") || !STRCASECMP(arg_ptr, "--ignoreenvironments") || !STRCASECMP(arg_ptr, "-ignoreenvironments") ) { ignore_environments = 1; } } /* Make sure we got required arguments. */ status = PConfPrereqCheck( platforms_ini, argc, argv ); switch(status) { case -1: fprintf( stderr, "%s: Cannot open platforms configuration file.\n", (argc > 1) ? argv[1] : platforms_ini ); fprintf( stderr, "This file is used to configure generation of the output Makefile\n\ used in compiling the program source, it should be specified as the\n\ first argument. If you cannot locate the platforms configuration file,\n\ notify the vendor that this file is missing.\n" ); DO_FREE_LOCALS return(1); break; case -2: /* Print help. */ PConfPrintHelp((argc > 0) ? argv[0] : NULL); DO_FREE_LOCALS return(4); break; case -3: /* Need to specify a platform. */ printf("You must specify a supported platform to configure for.\n"); /* Set print platforms level to 0, this will cause it to print * a brief list of platforms farther below. */ print_platforms_level = 0; break; default: break; } /* Begin parsing arguments. */ /* Get platforms.ini if specified. */ if(argc > 1) { FREE(platforms_ini); platforms_ini = STRDUP(argv[1]); } /* Get platform name. */ if(argc > 2) { FREE(platform_name); platform_name = STRDUP(argv[2]); } /* Parse the rest of the arguments. */ for(i = 2; i < argc; i++) { arg_ptr = (const char *)argv[i]; if(arg_ptr == NULL) continue; /* List all platforms with extended details. */ if(STRCASEPFX(arg_ptr, "--list_a") || STRCASEPFX(arg_ptr, "-list_a") || STRCASEPFX(arg_ptr, "--lista") || STRCASEPFX(arg_ptr, "-lista") ) { const char *cstrptr; print_platforms_level = 3; /* List specific platform? */ cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(specific_platform); specific_platform = STRDUP(cstrptr); } } /* List platforms. */ else if(STRCASEPFX(arg_ptr, "--list") || STRCASEPFX(arg_ptr, "-list") ) { const char *cstrptr; print_platforms_level = 1; /* List specific platform? */ cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(specific_platform); specific_platform = STRDUP(cstrptr); } } /* If parameter is not parsed yet and its the third one * then take it as the platform name. */ else if(i == 2) { FREE(specific_platform); specific_platform = STRDUP(arg_ptr); } } /* Allocate program core structure. */ core_ptr = (pconf_core_struct *)calloc( 1, sizeof(pconf_core_struct) ); if(core_ptr == NULL) { /* Free allocated resources. */ DO_FREE_LOCALS return(3); } else { const char *cstrptr; cstrptr = (const char *)GETENV("COLUMNS"); if(cstrptr == NULL) cstrptr = (const char *)GETENV("SCREEN_WIDTH"); if(cstrptr == NULL) cstrptr = (const char *)GETENV("SCREENWIDTH"); if(cstrptr != NULL) core_ptr->screen_width = atoi(cstrptr); core_ptr->verbose = verbose; core_ptr->warnings = warnings; core_ptr->colors = colors; core_ptr->interactive = interactive; core_ptr->force = force; core_ptr->ignore_environments = ignore_environments; } /* Load platforms configuration. */ status = PConfLoadPlatformsFromFile(core_ptr, platforms_ini); if(status) { /* Free allocated resources. */ PConfFreeCore(core_ptr); core_ptr = NULL; DO_FREE_LOCALS return(1); } /* We only want to print the platforms and exit? */ if(print_platforms_level >= 0) { PConfPrintPlatforms( core_ptr, core_ptr->platform, core_ptr->total_platforms, specific_platform, print_platforms_level, 0 ); if(print_platforms_level == 0) { printf( "\n\ For more details and features available on each platform, specify the\n\ --listall argument. To configure for a particular platform, just specify\n\ that platform's name.\n" ); } /* Free allocated resources. */ PConfFreeCore(core_ptr); core_ptr = NULL; DO_FREE_LOCALS return(4); } /* Check if selected platform is defined. */ selected_platform = PConfMatchPlatformByName( core_ptr->platform, core_ptr->total_platforms, specific_platform, &selected_platform_num ); if(selected_platform == NULL) { /* Specified platform does not exist. */ fprintf( stderr, "%s: ", specific_platform ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE); fprintf( stderr, "No such platform.\n" ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT); if(core_ptr->message_platform_unsupported == NULL) { fprintf( stderr, "Use argument --listall to list available platforms.\n" ); } else { fprintf( stderr, "%s\n", core_ptr->message_platform_unsupported ); } /* Free allocated resources. */ PConfFreeCore(core_ptr); core_ptr = NULL; DO_FREE_LOCALS return(2); } /* Move selected platform from the list into the core * structure's selected_platform. */ core_ptr->selected_platform = selected_platform; /* Remove platform pointer from the core's list. */ if((selected_platform_num >= 0) && (selected_platform_num < core_ptr->total_platforms) ) core_ptr->platform[selected_platform_num] = NULL; /* Deallocate all loaded platforms on the core structure * except for the selected one since we marked it NULL on * the list and it won't get deleted. */ PConfFreePlatforms( &core_ptr->platform, &core_ptr->total_platforms ); /* Got selected platform `selected_platform' at this point. */ /* Print configure startup message. */ if(selected_platform->name != NULL) printf("Configuring for platform `%s'...\n", selected_platform->name ); if(core_ptr->message_configure_startup != NULL) printf("%s\n", core_ptr->message_configure_startup ); /* Apply given command line and environment arguments and * apply them to the selected platform. */ PConfApplyArgsToPlatform( core_ptr, selected_platform, argc, argv ); /* Check if all features and dependencies in the platform * exist. */ status = PConfCheckDepends( core_ptr, selected_platform ); /* How many failed dependancies did we get? */ if(status > 0) { if(core_ptr->warnings) { if(core_ptr->force) { fprintf(stderr, "*** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE); fprintf( stderr, "%i failed %s ignored (because --force used)!", status, (status > 1) ? "dependencies" : "dependency" ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT); fprintf(stderr, " ***\n"); } else { fprintf(stderr, "*** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE); fprintf( stderr, "%i failed %s!", status, (status > 1) ? "dependencies" : "dependency" ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT); fprintf(stderr, " ***\n"); } } /* If not forcing, then we need to exit now. */ if(!core_ptr->force) { if(core_ptr->message_depend_failed != NULL) { fprintf( stderr, "%s\n", core_ptr->message_depend_failed ); } /* Free allocated resources. */ PConfFreeCore(core_ptr); core_ptr = NULL; DO_FREE_LOCALS return(1); } } else { if(core_ptr->verbose) { /* printf("*** "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS); printf("All dependencies found!"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); printf("***\n"); */ } } /* Print review of compiler configuration. */ if(core_ptr->verbose) { PConfPrintHR(core_ptr); PConfSetColor(core_ptr, stdout, PCONF_COLOR_HEADING); printf("Configuration Review:\n\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); PConfPrintPlatform(core_ptr, selected_platform, 3, 1); printf("\n"); PConfPrintHR(core_ptr); if(core_ptr->interactive) { } } /* Generate output Makefile. */ PConfGenerateOutputMakefile( core_ptr, selected_platform ); /* Print configuration success message. */ PConfSetColor(core_ptr, stdout, PCONF_COLOR_HEADING); printf("\nPlatform configuration completed!\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT); /* Print success message? */ if(core_ptr->message_success != NULL) { PConfPrintHR(core_ptr); printf("%s\n", core_ptr->message_success ); } /* Begin shutdown. */ /* Deallocate core structure. */ PConfFreeCore(core_ptr); core_ptr = NULL; /* Free allocated resources. */ DO_FREE_LOCALS #undef DO_FREE_LOCALS return(0); } searchandrescue_1.5.0/pconf/README0000644000175000017500000000267507303153732015744 0ustar jessejesse P L A T F O R M C O N F I G U R A T O R ABOUT ----- This is a very experimental Makefile generator, designed to generate a Makefile suitable for compiling a program based on information from a list of platforms and specifica values for each one. For those of you familiar with AutoConf, this basically works just like it with more or less features but nearly identical user-end syntax. Platform Configurator was created by WolfPack Entertainment due to frustration from AutoConf and certain issues that just didn't tayor AutoConf for our needs. We understand and respect those who successfully use AutoConf, however we were not fortunate to get it working in the past two years and rather than expend more time on it we decided to `reinvent the wheel'. In which case to our delights the new design has worked out better than we anticipated. Note that Platform Configurator is fully documented, if you are a developer and interested in further understanding then please read the file FORMAT which describes the configuration file format that pconf uses. Platform Configurator is not distributed in any means other than with WPE's software, however it is under GPL license. We grant you the right to use pconf if you find it useful but you will have to rip it out of the package it came from. We are happy to answer support questions that you may have, contact WPE if you need assistance http://wolfpack.twu.net/contacts.html searchandrescue_1.5.0/pconf/makefile_append.ini0000644000175000017500000000012607303153734020660 0ustar jessejesseBIN = yerf CC = cc $(BIN): $(CC) yerf.c -o $(BIN) all: $(BIN) clean: @echo "Clean" searchandrescue_1.5.0/pconf/fio.c0000644000175000017500000011317207303153733016001 0ustar jessejesse#include "pconf.h" static void PConfLoadPlatformsSanitizeLine(char *s); void PConfFreePlatform(platform_struct *platform_ptr); void PConfFreePlatforms( platform_struct ***list, int *total ); int PConfLoadPlatformsFromFile( pconf_core_struct *core_ptr, const char *filename ); int PConfLoadThisPlatformFromFile( pconf_core_struct *core_ptr, const char *filename ); void PConfGenerateOutputMakefile( pconf_core_struct *core_ptr, platform_struct *platform_ptr ); /* * Strips string s of all '\n' characters and spaces. */ static void PConfLoadPlatformsSanitizeLine(char *s) { char *sp; if(s == NULL) return; /* Strip spaces. */ STRSTRIP(s); /* Strip new lines. */ sp = s; /* Itterate through string. */ while((*sp) != '\0') { /* Is current character a newline? */ if(ISCR(*sp)) { char *sp2 = sp; /* Shorten string by one character at current * position. */ while((*sp2) != '\0') { (*sp2) = *(sp2 + 1); sp2++; } /* Do not itterate to next (since we shortend). */ } else { sp++; } } return; } /* * Deallocates the given platform structure and its allocated * substructures. */ void PConfFreePlatform(platform_struct *platform_ptr) { int n, j; feature_struct *feature_ptr; depend_struct *depend_ptr; if(platform_ptr == NULL) return; /* Deallocate all features. */ for(n = 0; n < platform_ptr->total_features; n++) { feature_ptr = platform_ptr->feature[n]; if(feature_ptr == NULL) continue; /* Deallocate all library dependancy structures. */ for(j = 0; j < feature_ptr->total_depends; j++) { depend_ptr = feature_ptr->depend[j]; if(depend_ptr == NULL) continue; FREE(depend_ptr->name); FREE(depend_ptr->description); STRFREEARRAY( depend_ptr->path, depend_ptr->total_paths ); STRFREEARRAY( depend_ptr->grep_string, depend_ptr->total_grep_strings ); FREE(depend_ptr->os_name); FREE(depend_ptr->machine_name); FREE(depend_ptr); } FREE(feature_ptr->depend); feature_ptr->depend = NULL; feature_ptr->total_depends = 0; FREE(feature_ptr->name); FREE(feature_ptr->description); FREE(feature_ptr->url_homepage); FREE(feature_ptr->url_download); FREE(feature_ptr->cflags); FREE(feature_ptr->inc_dirs); FREE(feature_ptr->libs); FREE(feature_ptr->lib_dirs); FREE(feature_ptr); } FREE(platform_ptr->feature); platform_ptr->feature = NULL; platform_ptr->total_features = 0; FREE(platform_ptr->name); FREE(platform_ptr->description); STRFREEARRAY( platform_ptr->path_header, platform_ptr->total_path_headers ); STRFREEARRAY( platform_ptr->path_library, platform_ptr->total_path_libraries ); STRFREEARRAY( platform_ptr->path_config, platform_ptr->total_path_configs ); STRFREEARRAY( platform_ptr->path_program, platform_ptr->total_path_programs ); STRFREEARRAY( platform_ptr->path_data, platform_ptr->total_path_datas ); FREE(platform_ptr->prefix); FREE(platform_ptr->cflags); FREE(platform_ptr->inc_dirs); FREE(platform_ptr->libs); FREE(platform_ptr->lib_dirs); FREE(platform_ptr->cc); FREE(platform_ptr->cpp); FREE(platform_ptr); return; } /* * Deallocates the list of platform structures and their allocated * substructures. */ void PConfFreePlatforms( platform_struct ***list, int *total ) { int i; if((list == NULL) || (total == NULL)) return; /* Deallocate all platforms. */ for(i = 0; i < (*total); i++) { PConfFreePlatform((*list)[i]); (*list)[i] = NULL; } if((*list) != NULL) { FREE(*list); (*list) = NULL; } (*total) = 0; return; } /* * Loads data from platform configuration file specified by filename * to the given core structure. * * Returns non-zero on error. */ int PConfLoadPlatformsFromFile( pconf_core_struct *core_ptr, const char *filename ) { int platform_num, feature_num, depend_num; FILE *fp; char *buf; const char *parm; platform_struct *platform_ptr; feature_struct *feature_ptr; depend_struct *depend_ptr; #define DO_RESET_CONTEXT_PTRS \ { \ platform_num = -1; \ platform_ptr = NULL; \ feature_num = -1; \ feature_ptr = NULL; \ depend_num = -1; \ depend_ptr = NULL; \ } if((core_ptr == NULL) || (filename == NULL)) return(-1); /* Delete any existing values on core structure? */ /* Open platforms configuratino file. */ fp = FOPEN(filename, "rb"); if(fp == NULL) { fprintf(stderr, "%s: Cannot open.\n", filename); return(-1); } /* Begin reading playforms configuration file. */ buf = NULL; DO_RESET_CONTEXT_PTRS do { buf = FSEEKNEXTPARAMETER( fp, buf, PCONF_CFG_COMMENT_CHAR, PCONF_CFG_DELIM_CHAR ); if(buf == NULL) break; /* Begin handling parameter. */ parm = (const char *)buf; /* Version. */ if(!STRCASECMP(parm, "Version")) { FSEEKNEXTLINE(fp); } /* Author. */ else if(!STRCASECMP(parm, "Author")) { FSEEKNEXTLINE(fp); } /* Program name. */ else if(!STRCASECMP(parm, "ProgramName")) { FSEEKNEXTLINE(fp); } /* Add new platform entry? */ else if(!STRCASECMP(parm, "Platform")) { char *val = FGETLINE(fp); /* If a platform was already in context, then clean it up * before loading a new one. */ if(platform_ptr != NULL) { /* Add other platform cleanup stuff here. */ } PConfLoadPlatformsSanitizeLine(val); DO_RESET_CONTEXT_PTRS /* Reset context pointers. */ /* Allocate a new platform structure. */ platform_num = core_ptr->total_platforms; core_ptr->total_platforms = platform_num + 1; core_ptr->platform = (platform_struct **)realloc( core_ptr->platform, core_ptr->total_platforms * sizeof(platform_struct *) ); if(core_ptr->platform == NULL) { core_ptr->total_platforms = 0; platform_num = -1; } else { core_ptr->platform[platform_num] = platform_ptr = (platform_struct *)calloc( 1, sizeof(platform_struct) ); } /* Set platform name. */ if(platform_ptr != NULL) platform_ptr->name = val; else FREE(val); } /* Add new feature entry to current platform? */ else if(!STRCASECMP(parm, "PlatformFeature")) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); depend_num = -1; depend_ptr = NULL; /* Is a platform currently in context? */ if(platform_ptr == NULL) { fprintf( stderr, "%s: Cannot specify parameter %s without a Platform in context.\n", filename, parm ); } else { /* Allocate a new feature structure. */ feature_num = platform_ptr->total_features; platform_ptr->total_features = feature_num + 1; platform_ptr->feature = (feature_struct **)realloc( platform_ptr->feature, platform_ptr->total_features * sizeof(feature_struct *) ); if(platform_ptr->feature == NULL) { platform_ptr->total_features = 0; feature_num = -1; feature_ptr = NULL; } else { platform_ptr->feature[feature_num] = feature_ptr = (feature_struct *)calloc( 1, sizeof(feature_struct) ); } /* Set feature name. */ if(feature_ptr != NULL) { feature_ptr->name = STRDUP(val); } } FREE(val); } /* Add new library dependancy entry to current feature? */ else if(!STRCASECMP(parm, "FeatureDependency") || !STRCASECMP(parm, "FeatureDependent") || !STRCASECMP(parm, "FeatureDepend") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Is a feature currently in context? */ if(feature_ptr == NULL) { fprintf( stderr, "%s: Cannot specify parameter %s without a PlatformFeature in context.\n", filename, parm ); } else { /* Allocate a new depend structure. */ depend_num = feature_ptr->total_depends; feature_ptr->total_depends = depend_num + 1; feature_ptr->depend = (depend_struct **)realloc( feature_ptr->depend, feature_ptr->total_depends * sizeof(depend_struct *) ); if(feature_ptr->depend == NULL) { feature_ptr->total_depends = 0; depend_num = -1; depend_ptr = NULL; } else { feature_ptr->depend[depend_num] = depend_ptr = (depend_struct *)calloc( 1, sizeof(depend_struct) ); } /* Set depend name. */ if(depend_ptr != NULL) { depend_ptr->name = STRDUP(val); } } FREE(val); } /* Description (for whatever is in context). */ else if(!STRCASECMP(parm, "Description")) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { FREE(depend_ptr->description); depend_ptr->description = STRDUP(val); } else if(feature_ptr != NULL) { FREE(feature_ptr->description); feature_ptr->description = STRDUP(val); } else if(platform_ptr != NULL) { FREE(platform_ptr->description); platform_ptr->description = STRDUP(val); } else if(core_ptr->warnings) { fprintf( stderr, "%s: Nothing in context for parameter `%s'.\n", filename, parm ); } FREE(val); } /* URL of home page (for whatever is in context). */ else if(!STRCASECMP(parm, "FeatureURLHomePage") || !STRCASECMP(parm, "URLHomePage") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->url_homepage); feature_ptr->url_homepage = STRDUP(val); } else if(core_ptr->warnings) { fprintf( stderr, "%s: Nothing in context for parameter `%s'.\n", filename, parm ); } FREE(val); } /* URL of download (for whatever is in context). */ else if(!STRCASECMP(parm, "FeatureURLDownload") || !STRCASECMP(parm, "URLDownload") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->url_download); feature_ptr->url_download = STRDUP(val); } else if(core_ptr->warnings) { fprintf( stderr, "%s: Nothing in context for parameter `%s'.\n", filename, parm ); } FREE(val); } /* Must exist (for whatever is in context). */ else if(!STRCASECMP(parm, "MustExist")) { char *val = FGETLINE(fp); int must_exist; PConfLoadPlatformsSanitizeLine(val); /* Parse must exist string. */ if((toupper(*val) == 'Y') || (toupper(*val) == 'T') ) must_exist = PCONF_MUST_EXIST_YES; else if((toupper(*val) == 'P')) must_exist = PCONF_MUST_EXIST_PREFERRED; else must_exist = PCONF_MUST_EXIST_NO; /* Handle by context. */ if(depend_ptr != NULL) { depend_ptr->must_exist = must_exist; } else if(feature_ptr != NULL) { feature_ptr->must_exist = must_exist; } else if(core_ptr->warnings) { fprintf( stderr, "%s: Nothing in context for parameter `%s'.\n", filename, parm ); } FREE(val); } /* Dependent entity type. */ else if(!STRCASECMP(parm, "DependentType") || !STRCASECMP(parm, "DependType") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { if(!STRCASECMP(val, "program")) depend_ptr->type = PCONF_DEP_TYPE_PROGRAM; else if(!STRCASECMP(val, "header")) depend_ptr->type = PCONF_DEP_TYPE_HEADER; else if(!STRCASECMP(val, "library")) depend_ptr->type = PCONF_DEP_TYPE_LIBRARY; else if(!STRCASECMP(val, "config")) depend_ptr->type = PCONF_DEP_TYPE_CONFIG; else if(!STRCASECMP(val, "data")) depend_ptr->type = PCONF_DEP_TYPE_DATA; else if(!STRCASECMP(val, "os")) depend_ptr->type = PCONF_DEP_TYPE_OS; else if(!STRCASECMP(val, "machine")) depend_ptr->type = PCONF_DEP_TYPE_MACHINE; else depend_ptr->type = PCONF_DEP_TYPE_OTHER; } FREE(val); } /* Dependent entity path. */ else if(!STRCASECMP(parm, "DependentPath") || !STRCASECMP(parm, "DependPath") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { STRLISTAPPEND( &depend_ptr->path, &depend_ptr->total_paths, val ); } FREE(val); } /* Dependent entity grep string. */ else if(!STRCASECMP(parm, "DependentGrepString") || !STRCASECMP(parm, "DependGrepString") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { STRLISTAPPEND( &depend_ptr->grep_string, &depend_ptr->total_grep_strings, val ); } FREE(val); } /* Dependent entity OS name. */ else if(!STRCASECMP(parm, "DependentOS") || !STRCASECMP(parm, "DependOS") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { FREE(depend_ptr->os_name); depend_ptr->os_name = STRDUP(val); if(depend_ptr->type != PCONF_DEP_TYPE_OS) fprintf( stderr, "%s: Warning: Value defined but type of dependency is not a OS.\n", parm ); } FREE(val); } /* Dependent entity machine name. */ else if(!STRCASECMP(parm, "DependentMachine") || !STRCASECMP(parm, "DependMachine") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(depend_ptr != NULL) { FREE(depend_ptr->machine_name); depend_ptr->machine_name = STRDUP(val); if(depend_ptr->type != PCONF_DEP_TYPE_MACHINE) fprintf( stderr, "%s: Warning: Value defined but type of dependency is not a machine.\n", parm ); } FREE(val); } /* Feature cflags. */ else if(!STRCASECMP(parm, "FeatureCFLAGS") || !STRCASECMP(parm, "FeatureCFLAG") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->cflags); feature_ptr->cflags = STRDUP(val); } FREE(val); } /* Feature include directories. */ else if(!STRCASECMP(parm, "FeatureINC_DIRS") || !STRCASECMP(parm, "FeatureINCDIRS") || !STRCASECMP(parm, "FeatureINC_DIR") || !STRCASECMP(parm, "FeatureINCDIR") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->inc_dirs); feature_ptr->inc_dirs = STRDUP(val); } FREE(val); } /* Feature libraries. */ else if(!STRCASECMP(parm, "FeatureLIBS") || !STRCASECMP(parm, "FeatureLIB") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->libs); feature_ptr->libs = STRDUP(val); } FREE(val); } /* Feature library directories. */ else if(!STRCASECMP(parm, "FeatureLIB_DIRS") || !STRCASECMP(parm, "FeatureLIBDIRS") || !STRCASECMP(parm, "FeatureLIB_DIR") || !STRCASECMP(parm, "FeatureLIBDIR") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(feature_ptr != NULL) { FREE(feature_ptr->lib_dirs); feature_ptr->lib_dirs = STRDUP(val); } FREE(val); } /* Platform search path for header files. */ else if(!STRCASECMP(parm, "PlatformSearchPathHeader") || !STRCASECMP(parm, "PlatformSearchPathInclude") || !STRCASECMP(parm, "PlatformSearchPathInc") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { STRLISTAPPEND( &platform_ptr->path_header, &platform_ptr->total_path_headers, val ); } FREE(val); } /* Platform search path for library files. */ else if(!STRCASECMP(parm, "PlatformSearchPathLibrary") || !STRCASECMP(parm, "PlatformSearchPathLib") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { STRLISTAPPEND( &platform_ptr->path_library, &platform_ptr->total_path_libraries, val ); } FREE(val); } /* Platform search path for configuration files. */ else if(!STRCASECMP(parm, "PlatformSearchPathConfiguration") || !STRCASECMP(parm, "PlatformSearchPathConfig") || !STRCASECMP(parm, "PlatformSearchPathEtc") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { STRLISTAPPEND( &platform_ptr->path_config, &platform_ptr->total_path_configs, val ); } FREE(val); } /* Platform search path for program files. */ else if(!STRCASECMP(parm, "PlatformSearchPathProgram") || !STRCASECMP(parm, "PlatformSearchPathProg") || !STRCASECMP(parm, "PlatformSearchPathBin") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { STRLISTAPPEND( &platform_ptr->path_program, &platform_ptr->total_path_programs, val ); } FREE(val); } /* Platform search path for data or other files. */ else if(!STRCASECMP(parm, "PlatformSearchPathData") || !STRCASECMP(parm, "PlatformSearchPathOther") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { STRLISTAPPEND( &platform_ptr->path_data, &platform_ptr->total_path_datas, val ); } FREE(val); } /* Platform PREFIX. */ else if(!STRCASECMP(parm, "PlatformPREFIX") || !STRCASECMP(parm, "PREFIX") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->prefix); platform_ptr->prefix = STRDUP(val); } FREE(val); } /* Platform CFLAGS. */ else if(!STRCASECMP(parm, "PlatformCFLAGS") || !STRCASECMP(parm, "CFLAGS") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->cflags); platform_ptr->cflags = STRDUP(val); } FREE(val); } /* Platform INC_DIRS. */ else if(!STRCASECMP(parm, "PlatformINC_DIRS") || !STRCASECMP(parm, "INC_DIRS") || !STRCASECMP(parm, "PlatformINC_DIR") || !STRCASECMP(parm, "INC_DIR") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->inc_dirs); platform_ptr->inc_dirs = STRDUP(val); } FREE(val); } /* Platform LIBS. */ else if(!STRCASECMP(parm, "PlatformLIBS") || !STRCASECMP(parm, "LIBS") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->libs); platform_ptr->libs = STRDUP(val); } FREE(val); } /* Platform LIB_DIRS. */ else if(!STRCASECMP(parm, "PlatformLIB_DIRS") || !STRCASECMP(parm, "LIB_DIRS") || !STRCASECMP(parm, "PlatformLIB_DIR") || !STRCASECMP(parm, "LIB_DIR") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->lib_dirs); platform_ptr->lib_dirs = STRDUP(val); } FREE(val); } /* Platform C compiler. */ else if(!STRCASECMP(parm, "PlatformCC") || !STRCASECMP(parm, "CC") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->cc); platform_ptr->cc = STRDUP(val); } FREE(val); } /* Platform C++ compiler. */ else if(!STRCASECMP(parm, "PlatformCPP") || !STRCASECMP(parm, "CPP") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); /* Handle by context. */ if(platform_ptr != NULL) { FREE(platform_ptr->cpp); platform_ptr->cpp = STRDUP(val); } FREE(val); } /* Output Makefile. */ else if(!STRCASECMP(parm, "MakefileOutput") || !STRCASECMP(parm, "MakefileOut") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->makefile_output); core_ptr->makefile_output = STRDUP(val); FREE(val); } /* Input Makefile prepended. */ else if(!STRCASECMP(parm, "MakefileInputPrepend") || !STRCASECMP(parm, "MakefileInputPre") || !STRCASECMP(parm, "MakefileInPrepend") || !STRCASECMP(parm, "MakefileInPre") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->makefile_input_prepend); core_ptr->makefile_input_prepend = STRDUP(val); FREE(val); } /* Input Makefile append. */ else if(!STRCASECMP(parm, "MakefileInputAppend") || !STRCASECMP(parm, "MakefileInAppend") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->makefile_input_append); core_ptr->makefile_input_append = STRDUP(val); FREE(val); } /* This platform information file. */ else if(!STRCASECMP(parm, "ThisPlatformInfo")) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); if(PConfLoadThisPlatformFromFile(core_ptr, val)) { fprintf(stderr, "%s: Could not read this site platform information file.\n", val ); } FREE(val); } /* Message configure start up. */ else if(!STRCASECMP(parm, "MessageConfigurationStartup") || !STRCASECMP(parm, "MessageConfiguringStartup") || !STRCASECMP(parm, "MessageConfigStartup") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->message_configure_startup); core_ptr->message_configure_startup = STRDUP(val); FREE(val); } /* Message platform unsupported. */ else if(!STRCASECMP(parm, "MessagePlatformUnsupported")) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->message_platform_unsupported); core_ptr->message_platform_unsupported = STRDUP(val); FREE(val); } /* Message dependency failed. */ else if(!STRCASECMP(parm, "MessageDependencyFailed") || !STRCASECMP(parm, "MessageDependentFailed") || !STRCASECMP(parm, "MessageDependFailed") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->message_depend_failed); core_ptr->message_depend_failed = STRDUP(val); FREE(val); } /* Message success. */ else if(!STRCASECMP(parm, "MessageSuccess") || !STRCASECMP(parm, "MessageSucc") ) { char *val = FGETLINE(fp); PConfLoadPlatformsSanitizeLine(val); FREE(core_ptr->message_success); core_ptr->message_success = STRDUP(val); FREE(val); } else { if(core_ptr->warnings) fprintf( stderr, "%s: Unsupported parameter `%s'.\n", filename, parm ); FSEEKNEXTLINE(fp); } } while(1); /* Close platforms file. */ FCLOSE(fp); fp = NULL; DO_RESET_CONTEXT_PTRS #undef DO_RESET_CONTEXT_PTRS return(0); } /* * Loads information from the `this platform' configuration file * which specifies information about the platform this program is * running on into the given core structure. */ int PConfLoadThisPlatformFromFile( pconf_core_struct *core_ptr, const char *filename ) { FILE *fp; char *buf; if((core_ptr == NULL) || (filename == NULL)) return(-1); fp = FOPEN(filename, "rb"); if(fp == NULL) return(-1); /* Begin reading each line. */ /* Line 1: OS name. */ buf = FGETLINE(fp); if(buf != NULL) { FREE(core_ptr->os_name); core_ptr->os_name = STRDUP(buf); } FREE(buf); /* Line 2: OS version (or release). */ buf = FGETLINE(fp); if(buf != NULL) { } FREE(buf); /* Line 3: Machine name. */ buf = FGETLINE(fp); if(buf != NULL) { FREE(core_ptr->machine_name); core_ptr->machine_name = STRDUP(buf); } FREE(buf); /* Ignore additional lines. */ /* Close platforms file. */ FCLOSE(fp); fp = NULL; return(0); } /* * Generates the output Makefile from the data on the given * core structure and platform. */ void PConfGenerateOutputMakefile( pconf_core_struct *core_ptr, platform_struct *platform_ptr ) { int i; FILE *fp_in, *fp_out; const char *makefile_output, *makefile_input_prepend, *makefile_input_append; feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL)) return; makefile_output = (const char *)core_ptr->makefile_output; makefile_input_prepend = (const char *)core_ptr->makefile_input_prepend; makefile_input_append = (const char *)core_ptr->makefile_input_append; /* Use defaults as needed. */ if(makefile_output == NULL) makefile_output = "Makefile"; /* Generate output Makefile. */ fp_out = FOPEN(makefile_output, "w"); if(fp_out == NULL) { /* Error generating output Makefile. */ fprintf( stderr, "%s: Cannot create.\n", makefile_output ); return; } printf("Generating output Makefile `%s'...\n", makefile_output ); /* Add input prepend file data if any. */ fp_in = FOPEN(makefile_input_prepend, "rb"); if(fp_in != NULL) { int c; do { c = FGETC(fp_in); if(c == EOF) break; FPUTC(c, fp_out); } while(1); FCLOSE(fp_in); fp_in = NULL; } /* Begin writing platform specific definations to output * Makefile. */ /* PREFIX. */ if(platform_ptr->prefix != NULL) { fprintf(fp_out, "PREFIX = %s", platform_ptr->prefix ); FPUTC('\n', fp_out); FPUTC('\n', fp_out); } /* CFLAGS. */ fprintf(fp_out, "CFLAGS =" ); if(platform_ptr->cflags != NULL) fprintf(fp_out, " %s", platform_ptr->cflags ); for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; if(feature_ptr->must_exist != PCONF_MUST_EXIST_YES) continue; if(feature_ptr->cflags != NULL) fprintf(fp_out, " %s", feature_ptr->cflags ); } FPUTC('\n', fp_out); FPUTC('\n', fp_out); /* INC_DIRS. */ fprintf(fp_out, "INC_DIRS =" ); if(platform_ptr->inc_dirs != NULL) fprintf(fp_out, " %s", platform_ptr->inc_dirs ); for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; if(feature_ptr->must_exist != PCONF_MUST_EXIST_YES) continue; if(feature_ptr->inc_dirs != NULL) fprintf(fp_out, " %s", feature_ptr->inc_dirs ); } FPUTC('\n', fp_out); FPUTC('\n', fp_out); /* LIBS. */ fprintf(fp_out, "LIBS =" ); if(platform_ptr->libs != NULL) fprintf(fp_out, " %s", platform_ptr->libs ); for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; if(feature_ptr->must_exist != PCONF_MUST_EXIST_YES) continue; if(feature_ptr->libs != NULL) fprintf(fp_out, " %s", feature_ptr->libs ); } FPUTC('\n', fp_out); FPUTC('\n', fp_out); /* LIB_DIRS. */ fprintf(fp_out, "LIB_DIRS =" ); if(platform_ptr->lib_dirs != NULL) fprintf(fp_out, " %s", platform_ptr->lib_dirs ); for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; if(feature_ptr->must_exist != PCONF_MUST_EXIST_YES) continue; if(feature_ptr->lib_dirs != NULL) fprintf(fp_out, " %s", feature_ptr->lib_dirs ); } FPUTC('\n', fp_out); FPUTC('\n', fp_out); /* CC. */ if(platform_ptr->cc != NULL) { fprintf(fp_out, "CC = %s", platform_ptr->cc ); FPUTC('\n', fp_out); FPUTC('\n', fp_out); } /* CPP. */ if(platform_ptr->cpp != NULL) { fprintf(fp_out, "CPP = %s", platform_ptr->cpp ); FPUTC('\n', fp_out); FPUTC('\n', fp_out); } /* Add input append file data if any. */ fp_in = FOPEN(makefile_input_append, "rb"); if(fp_in != NULL) { int c; do { c = FGETC(fp_in); if(c == EOF) break; FPUTC(c, fp_out); } while(1); FCLOSE(fp_in); fp_in = NULL; } /* Close output Makefile. */ FCLOSE(fp_out); fp_out = NULL; return; } searchandrescue_1.5.0/pconf/utils.c0000644000175000017500000003233107303153740016357 0ustar jessejesse#include "pconf.h" void FREE(void *p); int STRLEN(const char *s); int STRISYES(const char *s); char *STRDUP(const char *s); const char *STRCHR(const char *s, int c); void STRSTRIP(char *s); int STRCASECMP(const char *s1, const char *s2); int STRPFX(const char *str, const char *pfx); int STRCASEPFX(const char *str, const char *pfx); extern char *STRLISTAPPEND(char ***list, int *total, const char *s); extern void STRFREEARRAY(char **list, int total); char *GETENV(const char *parameter); FILE *FOPEN(const char *path, const char *mode); void FCLOSE(FILE *fp); int FGETC(FILE *fp); int FPUTC(int c, FILE *fp); void FSEEKNEXTLINE(FILE *fp); void FSEEKPASTSPACES(FILE *fp); char *FGETLINE(FILE *fp); char *FSEEKNEXTPARAMETER( FILE *fp, char *buf, char comment, char delim ); /* * Safer form of free(). */ void FREE(void *p) { if(p == NULL) return; free(p); return; } /* * Returns length of string, does not distingush error. */ int STRLEN(const char *s) { int len = 0; if(s == NULL) return(0); while((*s) != '\0') { len++; s++; } return(len); } /* * Returns true if string s implies a `yes'. */ int STRISYES(const char *s) { if(s == NULL) return(0); while(ISBLANK(*s)) s++; /* Yes? */ if(toupper(*s) == 'Y') return(1); /* On? */ if(STRCASEPFX(s, "ON")) return(1); /* True? */ if(toupper(*s) == 'T') return(1); /* All else non-zero number? */ if((*s) != '0') return(1); return(0); } /* * Safer form of strdup(). */ char *STRDUP(const char *s) { int len; char *sr = NULL, *sr_ptr; if(s == NULL) return(sr); len = STRLEN(s); sr = sr_ptr = (char *)malloc((len + 1) * sizeof(char)); if(sr == NULL) return(sr); while((*s) != '\0') { *sr_ptr++ = *s++; } (*sr_ptr) = '\0'; return(sr); } /* * Returns the position of c in s or NULL on no match. */ const char *STRCHR(const char *s, int c) { if((s == NULL) || ((char)c == '\0')) return(NULL); while((*s) != '\0') { if((*s) == (char)c) return(s); s++; } return(NULL); } /* * Strips blank characters leading and tailing string s. */ void STRSTRIP(char *s) { int tar, src, lead, tail; if(s == NULL) return; if((*s) == '\0') return; /* Strip leading blank characters. */ lead = 0; while(ISBLANK(s[lead])) lead++; if(lead > 0) { for(tar = 0, src = lead; s[src] != '\0'; tar++, src++) s[tar] = s[src]; s[tar] = '\0'; /* Calculate tail position. */ tail = (tar > 0) ? tar - 1 : 0; } else { /* Calculate tail position. */ tar = STRLEN(s); tail = (tar > 0) ? tar - 1 : 0; } /* Strip tailing blank characters. */ for(tar = tail; tar >= 0; tar--) { if(ISBLANK(s[tar])) s[tar] = '\0'; else break; } return; } /* * Returns 1 for no match and 0 for match. */ int STRCASECMP(const char *s1, const char *s2) { if((s1 == NULL) || (s2 == NULL) ) return(1); /* False. */ while((*s1) && (*s2)) { if(toupper(*s1) != toupper(*s2)) return(1); /* False. */ s1++; s2++; } if((*s1) == (*s2)) return(0); /* True. */ else return(1); /* False. */ } /* * Returns true if pfx is a prefix of str (case insensitive), * otherwise returns false. */ int STRPFX(const char *str, const char *pfx) { /* If either strings is NULL, return false. */ if((str == NULL) || (pfx == NULL) ) return(0); /* If pfx contains no characters, return false. */ if((*pfx) == '\0') return(0); /* Begin prefix matching. */ while((*pfx) != '\0') { if((*str) != (*pfx)) return(0); str++; pfx++; } return(1); } /* * Returns true if pfx is a prefix of str (case insensitive), * otherwise returns false. */ int STRCASEPFX(const char *str, const char *pfx) { /* If either strings is NULL, return false. */ if((str == NULL) || (pfx == NULL) ) return(0); /* If pfx contains no characters, return false. */ if((*pfx) == '\0') return(0); /* Begin prefix matching. */ while((*pfx) != '\0') { if(toupper(*str) != toupper(*pfx)) return(0); str++; pfx++; } return(1); } /* * Dupliates string s (may not be NULL) and adds it to the given * list. * * Reallocates the given list and increases the total. * * Returns pointer to duplicated string or NULL on error. */ char *STRLISTAPPEND(char ***list, int *total, const char *s) { int i; char *ns; if((list == NULL) || (total == NULL) || (s == NULL)) return(NULL); if((*total) < 0) (*total) = 0; ns = STRDUP(s); if(ns == NULL) return(NULL); i = (*total); (*total) = i + 1; (*list) = (char **)realloc( *list, (*total) * sizeof(char *) ); if((*list) == NULL) { (*total) = 0; FREE(ns); return(NULL); } (*list)[i] = ns; return(ns); } /* * Deallocates the given list of strings. */ void STRFREEARRAY(char **list, int total) { int i; if(list == NULL) return; for(i = 0; i < total; i++) FREE(list[i]); FREE(list); return; } /* * Safe form of getenv(). */ char *GETENV(const char *parameter) { if(parameter == NULL) return(NULL); return(getenv(parameter)); } /* * Opens a file, returns its handle or NULL on failure. Works * just like ansi fopen(). */ FILE *FOPEN(const char *path, const char *mode) { if((path == NULL) || (mode == NULL)) return(NULL); else return(fopen(path, mode)); } /* * Closes a file opened by FOPEN. */ void FCLOSE(FILE *fp) { if(fp == NULL) return; fclose(fp); return; } /* * Safe form of fgetc. */ int FGETC(FILE *fp) { if(fp == NULL) return(EOF); else return(fgetc(fp)); } /* * Safe form of fputc. */ int FPUTC(int c, FILE *fp) { if(fp == NULL) return(EOF); else return(fputc(c, fp)); } /* * Seeks to next line, escape sequences will be parsed. */ void FSEEKNEXTLINE(FILE *fp) { int c; if(fp == NULL) return; do { c = FGETC(fp); /* Escape sequence? */ if(c == '\\') c = FGETC(fp); /* New line? */ else if(ISCR(c)) break; } while(c != EOF); return; } /* * Seeks fp past any spaces. */ void FSEEKPASTSPACES(FILE *fp) { int c; if(fp == NULL) return; while(1) { c = FGETC(fp); if(c == EOF) break; if(ISBLANK(c)) continue; fseek(fp, -1, SEEK_CUR); break; } return; } /* * String is loaded literally and only escape sequence handled is * the occurance of two characters '\\' '\n' and where the '\n' * character will be saved into the return string. * * Spaces will not be striped, the fp will be positioned after the * non-escaped newline or EOF (whichever is encountered first). * * Return must be deallocated by calling function. */ char *FGETLINE(FILE *fp) { int c, i, len = 0; char *strptr = NULL; char *strptr2; if(fp == NULL) return(strptr); /* Begin reading string from file. */ /* Get first character. */ c = FGETC(fp); if(c == EOF) return(strptr); /* Read string. */ while(1) { i = len; /* Current string index i. */ len++; /* Current string length. */ /* Reallocate string buffer. */ strptr = (char *)realloc(strptr, len * sizeof(char)); if(strptr == NULL) break; strptr2 = &(strptr[i]); /* Pointer to current string index. */ (*strptr2) = c; /* Set new character value. */ /* End of the line? */ if((c == EOF) || ISCR(c) ) { (*strptr2) = '\0'; break; } /* Escape sequence? */ else if(c == '\\') { /* Read next character after backslash. */ c = FGETC(fp); if(c == EOF) { continue; } else if(ISCR(c)) { /* New line, store it as is. */ (*strptr2) = c; } else if(c == '\\') { /* Another backslash, store as a single backslash. */ (*strptr2) = c; } else { /* All other escaped characters leave as is * it will be set on the next loop. */ continue; } /* Read next character. */ c = FGETC(fp); } /* Regular character. */ else { /* Read next character. */ c = FGETC(fp); } } return(strptr); } /* * Fetches the next parameter found at the file position fp. * * If buf is NULL then a newly allocated string will be returned * containing the fetched parm. If buf is not NULL, then buf will * be realloc()'ed and returned as a new pointer containing * the fetched parm. * * If EOF is reached by the given fp position, then NULL will * be returned and the given buf will have been free()ed by this * function. */ char *FSEEKNEXTPARAMETER( FILE *fp, char *buf, char comment, char delim ) { #ifndef FREAD_ALLOC_CHUNK_SIZE # define FREAD_ALLOC_CHUNK_SIZE 8 #endif int c, buf_pos = 0, buf_len, buf_inc = FREAD_ALLOC_CHUNK_SIZE; if(fp == NULL) { FREE(buf); return(NULL); } /* Get length of buf (less than actual allocated is okay). */ buf_len = ((buf == NULL) ? 0 : STRLEN(buf)); /* Seek past spaces and comments to next parameter. */ while(1) { FSEEKPASTSPACES(fp); c = FGETC(fp); if(c == EOF) { FREE(buf); return(NULL); } else if(c == comment) { FSEEKNEXTLINE(fp); continue; } else if(ISCR(c)) { continue; } else { fseek(fp, -1, SEEK_CUR); break; } } /* Begin fetching this parm. */ while(1) { /* Get next char. */ c = FGETC(fp); if(c == EOF) { break; } /* Blank character reached? */ if(ISBLANK(c)) { /* Blank char reached, seek past delimiantor and position * fp at beginning of value. */ if(delim == '\0') { FSEEKPASTSPACES(fp); } else { FSEEKPASTSPACES(fp); /* Seek to deim or newline. */ do { c = FGETC(fp); if((c == EOF) || (c == delim)) break; if(ISCR(c)) { fseek(fp, -1, SEEK_CUR); break; } } while(1); FSEEKPASTSPACES(fp); } break; } /* CR reached? */ if(ISCR(c)) { fseek(fp, -1, SEEK_CUR); break; } /* Deliminator reached? */ if(c == delim) { FSEEKPASTSPACES(fp); break; } /* Need to allocate buffer? */ if(buf_pos <= buf_len) { buf_len += buf_inc; buf = (char *)realloc(buf, buf_len * sizeof(char)); if(buf == NULL) { FSEEKNEXTLINE(fp); return(NULL); } } buf[buf_pos] = (char)c; buf_pos++; } /* Put null terminating byte on buffer. */ if(c == EOF) { FREE(buf); buf = NULL; } else { if(buf_pos <= buf_len) { buf_len = buf_pos + 1; buf = (char *)realloc(buf, buf_len * sizeof(char)); if(buf == NULL) return(NULL); } buf[buf_pos] = '\0'; } return(buf); } searchandrescue_1.5.0/pconf/platforms.ini0000644000175000017500000001005211441262140017550 0ustar jessejesse# Platforms configuration file for Platform Configurator. # # See FORMAT for specifications about this file. # # *** THIS IS JUST A SAMPLE *** # MakefileOutput = Makefile.out MakefileInputPrepend = makefile_prepend.ini MakefileInputAppend = makefile_append.ini MessageConfigStartup = Checking your system... 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 resumt this configuration. MessageSuccess = Type 'make' to compile the program. # # Platforms section: # Platform = Linux Description = Penguins rule! PREFIX = /usr/ CFLAGS = -DPENGUINS -DHAVE_SDL_MIXER -Wno-write-strings LIBS = -lm -lSDL -lSDL_mixer LIB_DIR = PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/local/include/ PlatformSearchPathInclude = /usr/X11R6/include/ PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathLib = /usr/local/lib/ PlatformSearchPathLib = /usr/X11R6/lib/ PlatformSearchPathEtc = /etc/ PlatformSearchPathEtc = /usr/etc/ PlatformSearchPathEtc = /usr/local/etc/ PlatformSearchPathBin = /bin/ PlatformSearchPathBin = /usr/bin/ PlatformSearchPathBin = /usr/local/bin/ PlatformSearchPathBin = /usr/X11R6/bin/ PlatformSearchPathBin = /usr/games/ PlatformSearchPathData = /usr/share/ PlatformSearchPathData = /usr/share/games/ PlatformFeature = arch-i586 Description = For Intel Pentiums, just adds -march=i586 to CFLAGS MustExist = No PlatformFeature = X11 MustExist = Yes FeatureLIBS = -lX11 -lXext 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 = XNextEvent PlatformFeature = opengl Description = Implmentation of OpenGL, like 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 PlatformFeature = libjsw Description = For joystick support URLHomePage = http://wolfpack.twu.net/libjsw/ MustExist = Preferred FeatureLIBS = -ljsw FeatureDepend = libjsw-lib DependType = Library MustExist = Yes DependPath = libjsw.so DependGrepString = JSInit FeatureDepend = libjsw-devel DependType = Header MustExist = Yes DependPath = jsw.h DependGrepString = JSInit PlatformFeature = contraption MustExist = No FeatureDepend = contraption-lib DependType = Library MustExist = Yes DependPath = contraption.so DependGrepString = ContraptionInit PlatformFeature = alt MustExist = Preferred FeatureDepend = alt-lib DependType = Library MustExist = Yes DependPath = libalt.so DependGrepString = AltLibInit Platform = Windows Description = Awe this sucks PREFIX = C:\\ CFLAGS = -DASSIMILATE LIBS = LIB_DIR = searchandrescue_1.5.0/pconf/AUTHORS0000644000175000017500000000010507303153730016114 0ustar jessejesseCapt Taura Milana learfox2@hotmail.com http://furry.ao.net/~learfox/ searchandrescue_1.5.0/pconf/proc.c0000644000175000017500000010574407303153737016201 0ustar jessejesse#include "pconf.h" static int PConfEnableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ); static int PConfDisableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ); void PConfApplyArgsToPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int argc, char *argv[] ); static int PConfScanFileString( const char *filename, const char *s ); static char *PConfDependMatchFile( platform_struct *platform_ptr, int type, const char *path, struct stat *stat_buf ); static int PConfDependCheck( pconf_core_struct *core_ptr, platform_struct *platform_ptr, depend_struct *depend_ptr, const char *feature_name, int dep_cur, int dep_total ); int PConfCheckDepends( pconf_core_struct *core_ptr, platform_struct *platform_ptr ); /* * Enables the feature on the given platform specified by name, * marking its must_exist value to PCONF_MUST_EXIST_YES. * * Returns 0 on success, -1 on error, -2 no such feature. */ static int PConfEnableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ) { int feature_num; feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL) || (name == NULL)) return(-1); feature_ptr = PConfMatchFeatureByName( platform_ptr, name, &feature_num ); if(feature_ptr == NULL) return(-2); feature_ptr->must_exist = PCONF_MUST_EXIST_YES; return(0); } /* * Disables the feature on the given platform specified by name, * marking its must_exist value to PCONF_MUST_EXIST_NO. * * Returns 0 on success, -1 on error, -2 no such feature, -3 * if the feature's must_exist was initially PCONF_MUST_EXIST_YES. */ static int PConfDisableFeature( pconf_core_struct *core_ptr, platform_struct *platform_ptr, const char *name ) { int feature_num; feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL) || (name == NULL)) return(-1); feature_ptr = PConfMatchFeatureByName( platform_ptr, name, &feature_num ); if(feature_ptr == NULL) return(-2); /* Cannot disable this? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_YES) return(-3); feature_ptr->must_exist = PCONF_MUST_EXIST_NO; return(0); } /* * Applies environments and given arguments to the given platform's * values. */ void PConfApplyArgsToPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int argc, char *argv[] ) { int i, status; const char *arg_ptr; if((core_ptr == NULL) || (platform_ptr == NULL)) return; /* Can we initially get values from environment variables? */ if(!core_ptr->ignore_environments) { const char *cstrptr; /* Prefix. */ cstrptr = GETENV("PREFIX"); if(cstrptr != NULL) { FREE(platform_ptr->prefix); platform_ptr->prefix = STRDUP(cstrptr); } /* Compiler flags. */ cstrptr = GETENV("CFLAGS"); if(cstrptr != NULL) { FREE(platform_ptr->cflags); platform_ptr->cflags = STRDUP(cstrptr); } /* Include directories. */ cstrptr = GETENV("INC_DIRS"); if(cstrptr != NULL) { FREE(platform_ptr->inc_dirs); platform_ptr->inc_dirs = STRDUP(cstrptr); } /* Libraries. */ cstrptr = GETENV("LIBS"); if(cstrptr != NULL) { FREE(platform_ptr->libs); platform_ptr->libs = STRDUP(cstrptr); } /* Library directories. */ cstrptr = GETENV("LIB_DIRS"); if(cstrptr != NULL) { FREE(platform_ptr->lib_dirs); platform_ptr->lib_dirs = STRDUP(cstrptr); } /* C compiler. */ cstrptr = GETENV("CC"); if(cstrptr != NULL) { FREE(platform_ptr->cc); platform_ptr->cc = STRDUP(cstrptr); } /* C++ compiler. */ cstrptr = GETENV("CPP"); if(cstrptr != NULL) { FREE(platform_ptr->cpp); platform_ptr->cpp = STRDUP(cstrptr); } /* Parse LD library paths. */ cstrptr = GETENV("LD_LIBRARY_PATH"); if(cstrptr != NULL) { char *new_path, *strptr2; /* Itterate through value string. */ while((*cstrptr) != '\0') { /* Seek past ' ' and ':' characters. */ while(ISBLANK(*cstrptr) || ((*cstrptr) == ':')) cstrptr++; /* Skip "-L" prefixes. */ if(STRPFX(cstrptr, "-L")) { cstrptr += STRLEN("-L"); } /* Copy string at position of cstrptr. */ new_path = STRDUP(cstrptr); if(new_path != NULL) { /* Deliminate at next ' ' or ':' if any. */ strptr2 = (char *)STRCHR((char *)new_path, ':'); if(strptr2 != NULL) (*strptr2) = '\0'; strptr2 = (char *)STRCHR((char *)new_path, ' '); if(strptr2 != NULL) (*strptr2) = '\0'; /* Add this to the library path. */ STRLISTAPPEND( &platform_ptr->path_library, &platform_ptr->total_path_libraries, new_path ); if(core_ptr->verbose) printf( "Adding platform's library path: %s\n", new_path ); FREE(new_path); new_path = NULL; } /* Seek cstrptr to next argument, seeking to * next ' ' or ':' character. */ while(!ISBLANK(*cstrptr) && ((*cstrptr) != ':') && ((*cstrptr) != '\0') ) cstrptr++; } } } /* Itterate through each argument. */ for(i = 0; i < argc; i++) { arg_ptr = (const char *)argv[i]; if(arg_ptr == NULL) continue; /* Skip any args that don't begin with - or --. */ if((*arg_ptr) != '-') continue; /* Seek past '-' characters. */ while((*arg_ptr) == '-') arg_ptr++; /* Enable or with? */ if(STRCASEPFX(arg_ptr, "enable") || STRCASEPFX(arg_ptr, "with") ) { /* Enable what? */ const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr == NULL) cstrptr = STRCHR(arg_ptr, '-'); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; status = PConfEnableFeature( core_ptr, platform_ptr, cstrptr ); switch(status) { case -2: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf(stderr, "No such feature to enable.\n" ); } break; case -1: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf(stderr, "Error enabling this feature.\n" ); } break; } PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Disable or without? */ else if(STRCASEPFX(arg_ptr, "disable") || STRCASEPFX(arg_ptr, "without") || STRCASEPFX(arg_ptr, "with-out") || STRCASEPFX(arg_ptr, "with_out") ) { /* Disable what? */ const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr == NULL) cstrptr = STRCHR(arg_ptr, '-'); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; status = PConfDisableFeature( core_ptr, platform_ptr, cstrptr ); switch(status) { case -3: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "This feature is not allowed to be disabled.\n" ); } break; case -2: if(core_ptr->warnings) { fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf( stderr, "No such feature to disable.\n" ); } break; case -1: fprintf(stderr, "%s: ", cstrptr); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Error encountered while attempting to disable feature.\n" ); break; } PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '=' or '-' character.\n", arg_ptr ); } } /* Platform PREFIX? */ else if(STRCASEPFX(arg_ptr, "PREFIX") || STRCASEPFX(arg_ptr, "PlatformPREFIX") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->prefix); platform_ptr->prefix = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform CFLAGS? */ else if(STRCASEPFX(arg_ptr, "CFLAGS") || STRCASEPFX(arg_ptr, "PlatformCFLAGS") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->cflags); platform_ptr->cflags = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform INC_DIRS? */ else if(STRCASEPFX(arg_ptr, "INC_DIRS") || STRCASEPFX(arg_ptr, "PlatformINC_DIRS") || STRCASEPFX(arg_ptr, "INCDIRS") || STRCASEPFX(arg_ptr, "PlatformINCDIRS") || STRCASEPFX(arg_ptr, "INC_DIR") || STRCASEPFX(arg_ptr, "PlatformINC_DIR") || STRCASEPFX(arg_ptr, "INCDIR") || STRCASEPFX(arg_ptr, "PlatformINCDIR") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->inc_dirs); platform_ptr->inc_dirs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform LIBS? */ else if(STRCASEPFX(arg_ptr, "LIBS") || STRCASEPFX(arg_ptr, "PlatformLIBS") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->libs); platform_ptr->libs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } /* Platform LIB_DIRS? */ else if(STRCASEPFX(arg_ptr, "LIB_DIRS") || STRCASEPFX(arg_ptr, "PlatformLIB_DIRS") || STRCASEPFX(arg_ptr, "LIBDIRS") || STRCASEPFX(arg_ptr, "PlatformLIBDIRS") || STRCASEPFX(arg_ptr, "LIB_DIR") || STRCASEPFX(arg_ptr, "PlatformLIB_DIR") || STRCASEPFX(arg_ptr, "LIBDIR") || STRCASEPFX(arg_ptr, "PlatformLIBDIR") ) { const char *cstrptr = STRCHR(arg_ptr, '='); if(cstrptr != NULL) { cstrptr++; while(ISBLANK(*cstrptr)) cstrptr++; FREE(platform_ptr->lib_dirs); platform_ptr->lib_dirs = STRDUP(cstrptr); } else { if(core_ptr->warnings) fprintf( stderr, "--%s: Argument must have a value separated by a '='.\n", arg_ptr ); } } } return; } /* * Opens the file for reading and returns the number of occurances of * s found in the file. File must be a regular file. */ static int PConfScanFileString( const char *filename, const char *s ) { int c, matches = 0; FILE *fp; if((filename == NULL) || (s == NULL)) return(matches); if((*s) == '\0') return(matches); fp = FOPEN(filename, "rb"); if(fp == NULL) return(matches); do { c = FGETC(fp); if(c == EOF) break; /* Got start of matching string? */ if(c == (*s)) { /* Get next character and match string position. */ const char *sp = s + 1; c = FGETC(fp); /* Itterate sp. */ while((*sp) != '\0') { if(((*sp) != c) || (c == EOF)) break; sp++; c = FGETC(fp); } /* Got a match if sp itterated to end. */ if((*sp) == '\0') matches++; } } while(1); FCLOSE(fp); return(matches); } /* * Itterates through a list of paths on the given platform * structure and matches each one with the given path. * * Type specifies the depend type, one of PCONF_DEP_TYPE_*. * * On success, returns a dynamically allocated full path with * must be deallocated by the calling function. Can return NULL on * error. */ static char *PConfDependMatchFile( platform_struct *platform_ptr, int type, const char *path, struct stat *stat_buf ) { int i, len1, len2; char *base_path, *new_path; char **path_list = NULL; int total_paths = 0; if((platform_ptr == NULL) || (path == NULL)) return(NULL); switch(type) { case PCONF_DEP_TYPE_PROGRAM: path_list = platform_ptr->path_program; total_paths = platform_ptr->total_path_programs; break; case PCONF_DEP_TYPE_HEADER: path_list = platform_ptr->path_header; total_paths = platform_ptr->total_path_headers; break; case PCONF_DEP_TYPE_LIBRARY: path_list = platform_ptr->path_library; total_paths = platform_ptr->total_path_libraries; break; case PCONF_DEP_TYPE_CONFIG: path_list = platform_ptr->path_config; total_paths = platform_ptr->total_path_configs; break; case PCONF_DEP_TYPE_OS: case PCONF_DEP_TYPE_MACHINE: /* Should not call this function for checking these * dependencies. */ fprintf( stderr, "PConfDependMatchFile(): Internal error, dependency is not looking for a file.\n" ); return(NULL); break; default: /* PCONF_DEP_TYPE_DATA or PCONF_DEP_TYPE_OTHER. */ path_list = platform_ptr->path_data; total_paths = platform_ptr->total_path_datas; break; } /* Empty path list? */ if((path_list == NULL) || (total_paths < 1)) return(NULL); /* Itterate through search paths. */ new_path = NULL; len2 = STRLEN(path); for(i = 0; i < total_paths; i++) { base_path = path_list[i]; if(base_path == NULL) continue; /* Deallocate previous new path and get new one. */ FREE(new_path); new_path = NULL; /* Prefix paths and allocate new path. */ len1 = STRLEN(base_path); new_path = (char *)malloc((len1 + len2 + 10) * sizeof(char)); if(new_path != NULL) { if((len1 > 0) ? (base_path[len1 - 1] != DIR_DELIMINATOR) : 1 ) sprintf(new_path, "%s%c%s", base_path, DIR_DELIMINATOR, path ); else sprintf(new_path, "%s%s", base_path, path ); /* Exists? */ if(!stat(new_path, stat_buf)) return(new_path); } } /* Deallocate failed matched new path. */ FREE(new_path); new_path = NULL; return(NULL); } /* * Checks dependency on the given depend structure. * * Returns false on failure and true on success. */ static int PConfDependCheck( pconf_core_struct *core_ptr, platform_struct *platform_ptr, depend_struct *depend_ptr, const char *feature_name, int dep_cur, int dep_total ) { int i, found, missing_depend = 0; const char *path_ptr; char *new_path; const char *cstrptr; struct stat stat_buf; if((core_ptr == NULL) || (platform_ptr == NULL) || (depend_ptr == NULL)) return(0); if(core_ptr->verbose) printf("Feature: %s (%i of %i) Dependency: %s...\n", feature_name, dep_cur + 1, dep_total, depend_ptr->name ); else printf("Checking Dependency: %s...\n", depend_ptr->name); /* Special case handling for dependencies that do not look for * files. */ switch(depend_ptr->type) { case PCONF_DEP_TYPE_OS: /* Match operating system name. */ cstrptr = (const char *)depend_ptr->os_name; if((cstrptr == NULL) ? 1 : ((*cstrptr) == '\0')) { /* No name so impossible to match, return false. */ return(0); } else { if(core_ptr->os_name != NULL) { if(!STRCASECMP(core_ptr->os_name, cstrptr)) return(1); else return(0); } else { return(0); } } break; case PCONF_DEP_TYPE_MACHINE: /* Match machine name. */ cstrptr = (const char *)depend_ptr->machine_name; if((cstrptr == NULL) ? 1 : ((*cstrptr) == '\0')) { /* No name so impossible to match, return false. */ return(0); } else { if(core_ptr->machine_name != NULL) { if(!STRCASECMP(core_ptr->machine_name, cstrptr)) return(1); else return(0); } else { return(0); } } break; default: /* All other dependency checks, keep going. */ break; } /* Begin handling all other dependencies that look for files here. */ /* Itterate through dependency paths. */ new_path = NULL; for(i = 0; i < depend_ptr->total_paths; i++) { path_ptr = (const char *)depend_ptr->path[i]; if(path_ptr == NULL) continue; /* If we're not forcing, then stop checking dependencies * on just one failed dependency. */ if(!core_ptr->force && (missing_depend > 0)) break; /* Deallocate previous new path. */ FREE(new_path); new_path = NULL; /* Reset found marker. */ found = 0; /* Check if the path exists on this platform. */ new_path = PConfDependMatchFile( platform_ptr, depend_ptr->type, path_ptr, &stat_buf ); if(new_path != NULL) { if(core_ptr->verbose) { printf(" Scanning: %s...", new_path); fflush(stdout); } /* Is it a directory? */ #ifdef S_ISDIR if(S_ISDIR(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Directory)\n"); } found = 1; } /* Is it a character device? */ #ifdef S_ISCHR if(S_ISCHR(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Character Device)\n"); } found = 1; } /* Is it a block device? */ #ifdef S_ISBLK if(S_ISBLK(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Block Device)\n"); } found = 1; } /* Is it a FIFO pipe? */ #ifdef S_ISFIFO if(S_ISFIFO(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(FIFO Pipe)\n"); } found = 1; } /* Is it a socket? */ #ifdef S_ISSOCK if(S_ISSOCK(stat_buf.st_mode)) #else if(0) #endif { /* Accept this as is even if there are * strings to be greped. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK "); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf("(Socket)\n"); } found = 1; } /* Is it a regular file? */ #ifdef S_ISREG if(S_ISREG(stat_buf.st_mode)) #else if(1) #endif { /* Check for corresponding string for grepping on * this dependency structure. If there is one, then * grep for it. */ if((i >= 0) && (i < depend_ptr->total_grep_strings)) { const char *grep_string = depend_ptr->grep_string[i]; /* Grep string not NULL and not empty? */ if((grep_string == NULL) ? 0 : ((*grep_string) != '\0')) { if(PConfScanFileString( new_path, grep_string ) > 0) { if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } found = 1; } else { if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_FAILURE ); printf(" Failed\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } if(core_ptr->warnings) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Could not find `%s' in file %s!", grep_string, new_path ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); } } } else { /* Grep string is empty, imply always match. */ found = 1; if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } } } else { /* No grep string, so imply always match. */ if(core_ptr->verbose) { PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf(" OK\n"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); } /* Mark this dependency as found. */ found = 1; } } /* Not found? */ if(!found) { /* Increment missing dependencies count. */ missing_depend++; } } else { /* Object does not exist. */ if(core_ptr->warnings) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_WARNING ); fprintf( stderr, "Object `%s' not found in defined platform paths!", path_ptr ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); } /* Increment missing dependency count. */ missing_depend++; } } /* Itterate through dependency paths. */ /* Deallocate new path just in case. */ FREE(new_path); new_path = NULL; /* All depends met? */ if(missing_depend <= 0) return(1); else return(0); } /* * Checks for dependencies on all enabled features. * * Any feature's must_exist marked as PCONF_MUST_EXIST_PREFERRED will * be set to PCONF_MUST_EXIST_YES if they exist or set to * PCONF_MUST_EXIST_NO if they do not exist. * * Returns the number of failed dependencies who's must_exist * is set to PCONF_MUST_EXIST_YES. */ int PConfCheckDepends( pconf_core_struct *core_ptr, platform_struct *platform_ptr ) { int i, failed_depends = 0; int depend_progress_ratio = 0; /* In percent. */ feature_struct *feature_ptr; if((core_ptr == NULL) || (platform_ptr == NULL)) return(failed_depends); /* Itterate through each feature. */ for(i = 0; i < platform_ptr->total_features; i++) { feature_ptr = platform_ptr->feature[i]; if(feature_ptr == NULL) continue; /* Update progress ratio. */ if(platform_ptr->total_features > 0) depend_progress_ratio = (i + 1) * 100 / platform_ptr->total_features; /* Do not want this feature? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_NO) continue; /* Would like to have this feature (preffered)? */ if(feature_ptr->must_exist == PCONF_MUST_EXIST_PREFERRED) { int n, k = 0; depend_struct *depend_ptr; /* Check if we have dependencies. */ for(n = 0; n < feature_ptr->total_depends; n++) { depend_ptr = feature_ptr->depend[n]; if(depend_ptr == NULL) continue; if(depend_ptr->must_exist == PCONF_MUST_EXIST_YES) { /* Dependency found? */ if(!PConfDependCheck( core_ptr, platform_ptr, depend_ptr, feature_ptr->name, i, platform_ptr->total_features )) { k++; /* Do not count this as a failed dependency. */ } } } /* No failed dependencies? */ if(k == 0) { if(core_ptr->warnings) { printf( " Preferred feature `%s' ", feature_ptr->name ); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf("detected and enabled"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(".\n"); } /* No failed dependencies, so mark this as enabled. */ feature_ptr->must_exist = PCONF_MUST_EXIST_YES; } else { /* Got one or more failed dependency. */ if(core_ptr->warnings) { printf(" Preferred ("); PConfSetColor(core_ptr, stdout, PCONF_COLOR_SUCCESS ); printf("not required"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(") feature `%s' ", feature_ptr->name ); PConfSetColor(core_ptr, stdout, PCONF_COLOR_WARNING ); printf("not detected and disabled"); PConfSetColor(core_ptr, stdout, PCONF_COLOR_DEFAULT ); printf(".\n"); } /* Got failed dependencies, so mark this as disabled. */ feature_ptr->must_exist = PCONF_MUST_EXIST_NO; } } /* Must have this feature? */ else if(feature_ptr->must_exist == PCONF_MUST_EXIST_YES) { int n, k = 0; depend_struct *depend_ptr; /* Check if we have dependencies. */ for(n = 0; n < feature_ptr->total_depends; n++) { depend_ptr = feature_ptr->depend[n]; if(depend_ptr == NULL) continue; /* If not forcing and we got one or more failed * dependencies then we should give up immediatly. */ if(!core_ptr->force && (failed_depends > 0)) break; /* Check for dependency of feature only if feature * says the dependency must exist. */ if(depend_ptr->must_exist == PCONF_MUST_EXIST_YES) { /* Dependency found? */ if(!PConfDependCheck( core_ptr, platform_ptr, depend_ptr, feature_ptr->name, i, platform_ptr->total_features )) { k++; failed_depends++; } } } /* Got more than one failed dependency? */ if(k > 0) { PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " *** "); PConfSetColor(core_ptr, stderr, PCONF_COLOR_FAILURE ); fprintf( stderr, "Could not find all dependencies for required feature `%s'!", feature_ptr->name ); PConfSetColor(core_ptr, stderr, PCONF_COLOR_DEFAULT ); fprintf(stderr, " ***\n"); /* Got failed dependencies so mark this as disabled * if we are not forcing. */ if(!core_ptr->force) feature_ptr->must_exist = PCONF_MUST_EXIST_NO; /* This is a halting error, halt if not forcing. */ if(core_ptr->force) { if(core_ptr->verbose && core_ptr->warnings) fprintf( stderr, "*** Force enabled, continuing dependency check... ***\n" ); } else { break; } } } } /* Itterate through each feature. */ return(failed_depends); } searchandrescue_1.5.0/pconf/FORMAT0000644000175000017500000003104307303153731015765 0ustar jessejesse P L A T F O R M C O N F I G U R A T O R FILE FORMAT SPECIFICATION ABOUT ----- This file describes the format of the Platform Configurator's (pconf) platform configuration file format (platforms.ini). LEGEND ------ Comments start with a '#' character. Any '#' character found within a value or parameter will be interprited as part of that value or parameter (not interprited as a comment). Parameters may be intended with initial tabs or spaces. Values always start after the '=' character which is always following a parameter, ie: PREFIX = /usr/ If a value runs long, then do not put " around it. Instead use backslashes to escape as " characters are read literally, example: Description = The quick red foxes jumped over the "lazy" \ brown dog. PARAMETERS: GLOBAL ------------------ These parameters should be specified before all else, they do not need to reside in any configuration blocks or appear in any particular order other than appearing before any block parameters. MakefileOutput specifies the output Makefile to generate, example: MakefileOutput = Makefile.out MakefileInputPrepend specifies a text file who's contents will be literally prepended to the MakefileOutput, example: MakefileInputPrepend = makefile_prepend.ini MakefileInputAppend specifies a text file who's contents will be literally appended to the MakefileOutput, example: MakefileInputAppend = makefile_append.ini MessageConfigStartup specifies any arbitary string you want to show just before pconf starts scanning your system, example: MessageConfigStartup = Checking your system... MessagePlatformUnsupported specifies any arbitary string you want to show when the specified platform is not defined in the platforms.ini file, example: 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 specifies any arbitary string you want to show when one or more dependencies of the selected platform is not met, example: MessageDependFailed = Your missing some dependencies, use --force \ if you want to keep going next time. MessageSuccess specifies any arbitary string you want to show when pconf is done configuring and generating the MakefileOutput, example: MessageSuccess = Type `make' to compile the program. PARAMETER: PLATFORMS -------------------- Platform specifies the start of a `platform specification block', the value must be the name of the platform (preferably fetched from uname), example: Platform = Linux Platform = UNIX Once this value has been specified, subsequent platform related parameters affect this `platform specification block' untill another Platform is specified or end of file. Description specifies the description of this platform, it may contain some release notes or remarks that may not be readily apparent to the end user, example: Description = UNIX is generic, pick a more specific platform if \ available. PREFIX specifies the prepended directory for installing the program, for distributed UNIXes the value is /usr/local/ and plain UNIXes is /usr/. This value can be overridden from the command line using --prefix. Example: PREFIX = /usr/ CFLAGS specifies the standard compiler flags for the platform, do not include any compiler flags for particular features (see FeatureCFLAGS). Example: CFLAGS = -DNON_STANDARD -DWIERD_STUFF INC_DIRS specifies additional include directories that the platform does not normally search for, do not include any include directories for particular features (see FeaturesINC_DIRS). Example: INC_DIRS = -I/usr/nonstandard/include/ LIBS specifies the standard libraries for the platform that the program needs to link to, do not include any libraries for particular features (see FeatureLIBS). Example: LIBS = -lnonstandard -lm LIB_DIRS specifies the standard library paths for the platform that the libraries specified in the LIBS parameter need to look for, do not include any libraries for particular features (see FeatureLIB_DIRS). Example: LIB_DIRS = -I/usr/nonstandard/lib/ PlatformSearchPathInclude specifies an include path that is known to be on the platform (values must be absolute paths, may be specified multiple times), example: PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/nonstandard/include/ PlatformSearchPathLib specifies a library path that is known to be on the platform (values must be absolute paths, may be specified multiple times), example: PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathEtc specifies a configuration files path that is known to be on the platform (values must be absolute paths, may be specified multiple times), example: PlatformSearchPathEtc = /etc/ PlatformSearchPathEtc = /usr/etc/ PlatformSearchPathBin specifies a program files path that is known to be on the platform (values must be absolute paths, may be specified multiple times), example: PlatformSearchPathBin = /bin/ PlatformSearchPathBin = /sbin/ PlatformSearchPathBin = /usr/bin/ PlatformSearchPathBin = /usr/sbin/ PlatformSearchPathBin = /usr/games/ PlatformSearchPathBin = /usr/X11R6/bin/ PlatformSearchPathData specifies a data files path that is known to be on the platform (values must be absolute paths, may be specified multiple times), example: PlatformSearchPathData = /usr/share/icons/ PlatformSearchPathData = /usr/nonstandard/themes/ PARAMETER: FEATURE ------------------ PlatformFeature specifies the start of a `feature specification block', the value must be the name of the feature (any arbitary but user recognizeable name can be used), example: PlatformFeature = X Window Systems PlatformFeature = Imlib PlatformFeature = LibJSW This parameter must be specified after a Platform parameter. Once this value has been specified, subsequent feature related parameters affect this `feature specification block' untill another PlatformFeature is specified or end of file. Features can be enabled or disabled from the command line using --enable- or --disable- where is the name of a PlatformFeature specified value. Description specifies the description of this feature, it should contain a short sentence describing the propose of this feature and when to use it. Example: Description = For joystick support, only available on Linuxes URLHomePage specifies the url (ie used with web browsers and ftp clients) to specify the web page for this particular feature, example: URLHomePage = http://wolfpack.twu.net/libjsw/ URLDownload specifies the url of where to download required compoents for this feature, example: URLDownload = ftp://fox.mit.edu/pub/something.tar.bz2 MustExist specifies the default critera for existance of this feature; if the value is Yes then this feature must be found on the system or else configuration fails, if the value is No then this feature is not searched for on the syste unless the user specificalled --enable'ed this feature from the command line, if the value is Preferred then this feature is searched for on the system and will be enabled if it is found or disabled if it is not found, examples: MustExist = Yes MustExist = Preferred MustExist = No FeatureCFLAGS specifies a list of compiler flags to append to the CFLAGS parameter's value if this feature is found and enabled, example: FeatureCFLAGS = -DHAVE_X FeatureINC_DIRS specifies a list of include directories to append to the INC_DIRS parameter's value if this feature is found and enabled, example: FeatureINC_DIRS = -I/usr/nonstandard/include/ FeatureLIBS specifies a list of libraries to append to the LIBS parameter's value if this feature is found and enabled, example: FeatureLIBS = -lX11 -lXext FeatureLIB_DIR specifies a list of librariy directories to append to the LIB_DIRS parameter's value if this feature is found and enabled, example: FeatureLIB_DIR = -L/usr/X11R6/lib/ PARAMETER: FEATURE DEPENDENCY ----------------------------- FeatureDepend specifies the start of a `dependency specification block', the value must be the name of the dependency (preferably a conical package name), example: FeatureDepend = X11-lib This parameter must be specified after a PlatformFeature parameter. Once this value has been specified, subsequent dependency related parameters affect this `dependency specification block' untill another FeatureDepend is specified or end of file. DependType specifies the type of this dependency, valid values can be; Program, Library, Header, Config, or Data which will indicate the location of the dependency objects to be searched for in the paths (respectivly) PlatformSearchPathBin, PlatformSearchPathLib, PlatformSearchPathInclude, PlatformSearchPathEtc, and PlatformSearchPathData. Example: DependType = Library Which means this dependencie's files will be searched for in the paths defined by PlatformSearchPathLib parameters. MustExist specifies if this dependencie's objects must exist. This value should always be Yes. MustExist = Yes DependPath specifies the name of the object (partial path allowed as needed, but should never be absolute path). This value is searched for depending on this dependency type (specified by DependType) in the appropriate PlatformSearchPath* parameters, example: DependPath = libX11.so DependGrepString specifies the name of a string to search for in a matched dependent object (which means this parameter must be specified after each DependPath parameter!), example: DependPath = libX11.so DependGrepString = XOpenDisplay SAMPLES ------- Example of Linux platform support, this is just one platform section specifying Linux specific details and one feature for X Window Systems (Note that this is not a compelte Linux platform support, you may need to add more paths and related details): MakefileOutput = Makefile.out Platform = Linux Description = Penguins rule! PREFIX = /usr/ CFLAGS = LIBS = -lm LIB_DIR = PlatformSearchPathInclude = /usr/include/ PlatformSearchPathInclude = /usr/X11R6/include/ PlatformSearchPathLib = /lib/ PlatformSearchPathLib = /usr/lib/ PlatformSearchPathLib = /usr/X11R6/lib/ PlatformSearchPathEtc = /etc/ PlatformFeature = X Window Systems MustExist = Preferred FeatureLIBS = -lX11 -lXext 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 = XNextEvent When pconf is runned with the platforms.ini (that contains the above data) and the platform name "linux" the above will be matched and pconf will begin checking for any features and its dependencies. Since feature `X Window Systems' is set to Preferred, pconf will check if it exists and then decide to enable it or not: pconf platforms.ini linux To specifically require that `X Window Systems' be enabled: pconf platforms.ini linux --enable-"X Window Systems" And the same, with an override of the prefix: pconf platforms.ini linux --prefix=/tmp/ --enable-"X Window Systems" List of all platforms in any platforms.ini can be obtained with any of the following (incrementing in detail): pconf platforms.ini pconf platforms.ini --list pconf platforms.ini --listall The portion of the output Makefile (specified by MakefileOutput) generated by pconf will provide values for the parameters; PREFIX, CFLAGS, INC_DIRS, LIBS, LIB_DIRS, CC, and CPP. RFC --- Hopefully you have noticed by now that from the user end side this is pretty close to how AutoConf implments things with the option of specifying a preset platform and platforms configuration file which both can be specified via script. Platform Configurator was created due to the lack of documentation and problems our corperation has encountered with it. We understand that AutoConf has worked for others but with the time and effort that we have expended to adapt and use AutoConf has not been negateful over the option of creating our own pconf system. If you find pconf useful, you are free to use it under the GNU public license. Please send comments and questions to WPE, for list of contact addresses see http://wolfpack.twu.net/contacts.html searchandrescue_1.5.0/pconf/pconf.h0000644000175000017500000001711707303153735016342 0ustar jessejesse/* * cconf header file, all #included resources and prototypes used * by pconf must be specified here. * * None of pconf's sources #include anything or assume anything * defined that is not in here. * * See README and AUTHORS file for details of purpose and * maintainers. */ #ifndef PCONF_H #define PCONF_H #include #include #include #include #include #ifndef ISCR # define ISCR(c) (((c) == '\n') || ((c) == '\r')) #endif #ifndef ISBLANK # define ISBLANK(c) (((c) == ' ') || ((c) == '\t')) #endif #ifndef DIR_DELIMINATOR # define DIR_DELIMINATOR '/' #endif /* pconf specific definations, adjust as needed. */ #define PROG_NAME "Compiler Configurator" #define PROG_VERSION "0.0.1" #define PROG_VERSION_MAJOR 0 #define PROG_VERSION_MINOR 0 #define PROG_VERSION_RELEASE 1 /* Configuration file comment character. */ #define PCONF_CFG_COMMENT_CHAR '#' /* Configuration file parameter and value deliminator character. */ #define PCONF_CFG_DELIM_CHAR '=' /* ANSI color codes. */ #define PCONF_COLOR_DEFAULT 0 #define PCONF_COLOR_HEADING -1 #define PCONF_COLOR_SELECTABLE -3 #define PCONF_COLOR_SUCCESS 32 #define PCONF_COLOR_FAILURE 31 #define PCONF_COLOR_WARNING 33 /* Must exist codes. */ #define PCONF_MUST_EXIST_NO 0 /* Disable. */ #define PCONF_MUST_EXIST_PREFERRED 1 /* Enable if exists. */ #define PCONF_MUST_EXIST_YES 2 /* Must exist or fail. */ /* Dependancy structure. */ typedef struct { /* Dependent entity type, one of PCONF_DEP_TYPE_*. * This determines which search paths on the platform structure * to use for finding paths specified in this structure. */ #define PCONF_DEP_TYPE_OTHER 0 #define PCONF_DEP_TYPE_DATA 1 #define PCONF_DEP_TYPE_CONFIG 2 #define PCONF_DEP_TYPE_LIBRARY 3 #define PCONF_DEP_TYPE_HEADER 4 #define PCONF_DEP_TYPE_PROGRAM 5 #define PCONF_DEP_TYPE_OS 10 /* Operating system type. */ #define PCONF_DEP_TYPE_MACHINE 11 /* Machine type. */ int type; /* Name of this dependent entity (can be arbitary). */ char *name; /* Verbose description of this dependent entity. */ char *description; /* This dependent entity must exist, one of PCONF_MUST_EXIST_* * (but not PCONF_MUST_EXIST_PREFERRED). */ int must_exist; /* Entity file names to search for (the same file name may * need to be specified multiple times, see func_name member). */ char **path; int total_paths; /* Strings to search for corresponding index of files. Each * (non-empty) string is searched for in the specified paths * in the path member (if it is not a directory). */ char **grep_string; int total_grep_strings; /* Operating system name, used only if type is * PCONF_DEP_TYPE_OS (preferably value fetched from uname). */ char *os_name; /* Machine name, used only if type is * PCONF_DEP_TYPE_MACHINE (preferably value fetched from uname). */ char *machine_name; } depend_struct; /* Feature structure, optional requirements for any given platform. */ typedef struct { /* Name of this feature (can be arbitary). */ char *name; /* Verbose description of this feature. */ char *description; /* URL of home page. */ char *url_homepage; /* URL of download location. */ char *url_download; /* This feature must exist, one of PCONF_MUST_EXIST_*. */ int must_exist; /* List of dependant entities. */ depend_struct **depend; int total_depends; /* Extra info to append. */ char *cflags; char *inc_dirs; char *libs; char *lib_dirs; } feature_struct; /* Platform structure. */ typedef struct { /* Name of this platform, this value is used to match value * of platform from command line. */ char *name; /* Verbose description of this platform. */ char *description; /* List of features. */ feature_struct **feature; int total_features; /* Search paths for header files. */ char **path_header; int total_path_headers; /* Search paths for library files. */ char **path_library; int total_path_libraries; /* Search paths for configuration files. */ char **path_config; int total_path_configs; /* Search paths for program files. */ char **path_program; int total_path_programs; /* Search paths for data and other files, these paths * are used when a search path needs to be specified for * an object that dosen't really fall into the above * categories. */ char **path_data; int total_path_datas; /* Global options for this platform. */ char *prefix; char *cflags; char *inc_dirs; char *libs; char *lib_dirs; char *cc; /* C compiler. */ char *cpp; /* C++ compiler. */ } platform_struct; /* PConf core structure. */ typedef struct { int verbose; /* Print extra verbose messages. */ int warnings; /* Print warnings (if any). */ int colors; /* Enable ansi colors. */ int interactive; int force; /* Keep going even if errors encountered. */ int ignore_environments; /* Ignore environment variables. */ int screen_width; /* 0 for undefined. */ /* Loaded list of supported platforms. */ platform_struct **platform; int total_platforms; /* Pointer to selected platform. */ platform_struct *selected_platform; /* Output Makefile path. */ char *makefile_output; /* Input Makefile paths. */ char *makefile_input_prepend; char *makefile_input_append; /* Messages. */ char *message_configure_startup; char *message_platform_unsupported; char *message_depend_failed; char *message_success; /* Values fetched from the thisplatform.ini. */ char *os_name; char *machine_name; } pconf_core_struct; /* In fio.c */ extern void PConfFreePlatform(platform_struct *platform_ptr); extern void PConfFreePlatforms( platform_struct ***list, int *total ); extern int PConfLoadPlatformsFromFile( pconf_core_struct *core_ptr, const char *filename ); extern int PConfLoadThisPlatformFromFile( pconf_core_struct *core_ptr, const char *filename ); extern void PConfGenerateOutputMakefile( pconf_core_struct *core_ptr, platform_struct *platform_ptr ); /* In main.c */ extern void PConfSetColor( pconf_core_struct *core_ptr, FILE *stream, int color_code ); extern void PConfPrintHR(pconf_core_struct *core_ptr); extern feature_struct *PConfMatchFeatureByName( platform_struct *platform_ptr, const char *name, int *n ); /* In proc.c */ extern void PConfApplyArgsToPlatform( pconf_core_struct *core_ptr, platform_struct *platform_ptr, int argc, char *argv[] ); extern int PConfCheckDepends( pconf_core_struct *core_ptr, platform_struct *platform_ptr ); /* In utils.c */ extern void FREE(void *p); extern int STRLEN(const char *s); extern int STRISYES(const char *s); extern char *STRDUP(const char *s); extern const char *STRCHR(const char *s, int c); extern void STRSTRIP(char *s); extern int STRCASECMP(const char *s1, const char *s2); extern int STRPFX(const char *str, const char *pfx); extern int STRCASEPFX(const char *str, const char *pfx); extern char *STRLISTAPPEND(char ***list, int *total, const char *s); extern void STRFREEARRAY(char **list, int total); extern char *GETENV(const char *parameter); extern FILE *FOPEN(const char *path, const char *mode); extern void FCLOSE(FILE *fp); extern int FGETC(FILE *fp); extern int FPUTC(int c, FILE *fp); extern void FSEEKNEXTLINE(FILE *fp); extern void FSEEKPASTSPACES(FILE *fp); extern char *FGETLINE(FILE *fp); extern char *FSEEKNEXTPARAMETER( FILE *fp, char *buf, char comment, char delim ); #endif /* PCONF_H */ searchandrescue_1.5.0/prerm0000644000175000017500000000210211344253463015012 0ustar jessejesse#! /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.5.0/Makefile0000644000175000017500000000026611365575327015424 0ustar jessejesseALL_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.5.0/postinst0000644000175000017500000000241611344253463015560 0ustar jessejesse#! /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.5.0/distclean0000755000175000017500000000022110065722030015624 0ustar jessejesse#!/bin/sh echo "Cleaning for distribution..." chmod 755 include make clean ./configure --reset echo "Tree has been cleaned for distribution." searchandrescue_1.5.0/sar/0000755000175000017500000000000012026716153014532 5ustar jessejessesearchandrescue_1.5.0/sar/simmanage.c0000644000175000017500000005237410104532751016645 0ustar jessejesse#include #include #include #include #include "../include/disk.h" #include "sfm.h" #include "horizon.h" #include "sarreality.h" #include "sound.h" #include "obj.h" #include "sar.h" #include "objutils.h" #include "sartime.h" #include "simcb.h" #include "simutils.h" #include "simsurface.h" #include "simcontact.h" #include "simop.h" #include "simmanage.h" #include "config.h" static void SARSimGenerateLighteningPoints( sar_position_struct *point, int points, const sar_position_struct *pos, float width, float height ); int SARSimUpdateScene( sar_core_struct *core_ptr, sar_scene_struct *scene ); int SARSimUpdateSceneObjects( sar_core_struct *core_ptr, sar_scene_struct *scene ); #define POW(x,y) (((x) > 0.0f) ? pow(x,y) : 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 DEGTORAD(d) ((d) * PI / 180.0) #define RADTODEG(r) ((r) * 180.0 / PI) #define PLAY_SOUND(p) \ { if((opt->event_sounds) && (recorder != NULL)) { \ char *full_path = STRDUP((ISPATHABSOLUTE(p)) ? \ (p) : PrefixPaths(dname.global_data, (p)) \ ); \ SoundStartPlayVoid( \ recorder, full_path, 1.0, 1.0, 0, 0 \ ); \ free(full_path); \ } } /* * Generates random lightening points */ static void SARSimGenerateLighteningPoints( sar_position_struct *point, int points, const sar_position_struct *pos, float width, float height ) { /* Generate points starting at the cloud's base and go all the * way down to the ground, we need to start at the cloud base * as Z = 0 and reach the ground as Z = -pos->z * * The width of the cloud will help determine the amount of * "zigzagging" the lightening will make, the zigzagging will * be no more than 50% of the width * * The starting Z position z_cur will be from the base of the * cloud to 25% of the height */ int i; unsigned int seed = cur_millitime; sar_position_struct *pt, *last_pt = NULL; float z_cur = height * (SARRandomCoeff(seed) * 0.25f), z_inc = 0.0f; /* Set starting point, the origin of the lightening */ if(points >= 2) { last_pt = pt = &point[0]; /* Get first point */ /* Set origin of lightening */ pt->x = width * (SARRandomCoeff(seed) - 0.5f); pt->y = width * (SARRandomCoeff(seed) - 0.5f); pt->z = z_cur; /* Calculate absolute Z increment between points */ z_inc = (z_cur + pos->z) / (points - 1); z_cur -= z_inc; /* Increment for next point */ } /* Set subsequent points */ for(i = 1; i < points; i++) { pt = &point[i]; if(last_pt != NULL) { /* Set point using last point as a reference */ pt->x = last_pt->x + (width * (SARRandomCoeff(seed) - 0.5f) * 0.2f); pt->y = last_pt->y + (width * (SARRandomCoeff(seed) - 0.5f) * 0.2f); pt->z = z_cur; } /* Increment current Z position and record last point */ z_cur -= z_inc; last_pt = pt; } } /* * Updates the given scene structure's members (but does not update * any objects). * * Time of day will be updated on the scene, then along with the * primary light position light_pos and color light_color. * * Horizon texture will be (re)generated as need per a given interval * (every 5 minutes). * * Returns 0 on success and non-zero on error or memory pointer * change. */ int SARSimUpdateScene(sar_core_struct *core_ptr, sar_scene_struct *scene) { float scene_lumination_coeff, horizon_sat_max_coeff; int prev_tod_code, new_tod_code; sar_position_struct *pos; sar_color_struct *c; sar_scene_horizon_struct *horizon; snd_recorder_struct *recorder = core_ptr->recorder; const sar_option_struct *opt = &core_ptr->option; if(scene == NULL) return(-1); /* Converts hours into seconds */ #define HTOS(h) ((h) * 3600.0) /* Time Of Day */ /* Update time of day since midnight, in seconds */ scene->tod += (float)lapsed_millitime * time_compression / 1000.0f; /* Sanitize time of day */ while(scene->tod >= HTOS(24.0)) scene->tod -= HTOS(24.0); while(scene->tod < HTOS(0.0)) scene->tod += HTOS(24.0); /* Record previous time of day code */ prev_tod_code = scene->tod_code; /* Set time of day code depending on new time of day (which was * updated above) */ if(scene->tod < HTOS(6.0)) /* Before 6:00 am */ new_tod_code = SAR_TOD_CODE_NIGHT; else if(scene->tod < HTOS(7.0)) /* Before 7:00 am */ new_tod_code = SAR_TOD_CODE_DAWN; else if(scene->tod < HTOS(17.0)) /* Before 5:00 pm */ new_tod_code = SAR_TOD_CODE_DAY; else if(scene->tod < HTOS(18.0)) /* Before 6:00 pm */ new_tod_code = SAR_TOD_CODE_DUSK; else /* After 6:00 pm */ new_tod_code = SAR_TOD_CODE_NIGHT; scene->tod_code = new_tod_code; /* Set new tod_code */ /* Global Lumination */ /* Calculate global scene lumination coeff for time 4:00 to * 20:00, where 0.0 is darkest and 1.0 is brightest. Darkest * occures at 4:00 and 20:00, brightest is at 12:00 * * Also calculate horizon saturation extreme coefficient, the * coefficient to determine the amount of dawn/dusk saturation * on the horizon */ /* First calculate from -1.0 to 1.0 linearly where -1.0 is * at 4:00 and 1.0 is at 20:00 */ scene_lumination_coeff = (float)((scene->tod - HTOS(12.0)) / HTOS(8.0)); if(scene_lumination_coeff < 0.0f) { /* Before 12:00 */ float pow_coeff = (float)POW(-scene_lumination_coeff, 2); /* Horizon saturation coefficient, calculate from * scene lumination so far (with power of 2) */ horizon_sat_max_coeff = (float)CLIP( 1.0 - pow_coeff, 0.0, 1.0 ); /* Scene lumination; flip, change sign, and apply non-linear * curvature (power of 5) */ pow_coeff = (float)POW(-scene_lumination_coeff, 5); scene_lumination_coeff = (float)CLIP( 1.0 - pow_coeff, 0.0, 1.0 ); } else { /* 12:00 or later */ float pow_coeff = (float)POW(scene_lumination_coeff, 2); /* Horizon saturation coefficient, calculate from * scene lumination so far (with power of 2) */ horizon_sat_max_coeff = (float)CLIP( 1.0 - pow_coeff, 0.0, 1.0 ); /* Scene lumination; flip and apply non-linear * curvature (power of 5) */ pow_coeff = (float)POW(scene_lumination_coeff, 5); scene_lumination_coeff = (float)CLIP( 1.0 - pow_coeff, 0.0, 1.0 ); } /* Sun (Scene's Global Light) */ /* Move scene's global light position relative to the origin based * on the time of day. So this position is really an offset that * needs to be added to the actual camera's position * * The scene's global light is in a orbital pattern depending on * the time of day, to simulate it as the sun */ pos = &scene->light_pos; /* Scene global light position */ if(scene->tod > HTOS(12.0)) { float orbital_coeff; /* Afternoon or later, calculate orbital position coefficient * linearly from 12:00 (coeff 1.0) to 19:00 (coeff 0.0) */ orbital_coeff = (float)(1.0 - MIN( (scene->tod - HTOS(12.0)) / HTOS(7.0), 1.0 )); /* Calculate longitude aligned orbital position of light * relative to camera's XY plane */ pos->x = (float)(-cos(orbital_coeff * (0.5 * PI))); pos->y = 0.0f; /* Calculated later */ pos->z = (float)(sin(orbital_coeff * (0.5 * PI))); } else { float orbital_coeff; /* Morning, calculate orbital position coefficient * linearly from 2:00 (coeff 0.0) to 12:00 (coeff 1.0) */ orbital_coeff = (float)MAX( (scene->tod - HTOS(5.0)) / HTOS(7.0), 0.0 ); /* Calculate longitude aligned orbital position of light * relative to camera's XY plane */ pos->x = (float)(cos(orbital_coeff * (0.5 * PI))); pos->y = 0.0f; /* Calculated later */ pos->z = (float)(sin(orbital_coeff * (0.5 * PI))); } /* Apply latitude offset to scene's global light position */ if(1) { float lat_offset_deg = scene->dms_y_offset, lat_offset_rad, len; /* Calculate latitude offset in radians */ lat_offset_rad = (float)CLIP( DEGTORAD(lat_offset_deg), -0.5 * PI, 0.5 * PI ); pos->y = (float)(pos->y + sin(-lat_offset_rad)); /* pos->z = MAX(pos->z - sin(-lat_offset_rad), 0.0); */ /* Make into unit length */ len = (float)SFMHypot3(pos->x, pos->y, pos->z); if(len > 0.0f) { pos->x = pos->x / len; pos->y = pos->y / len; pos->z = pos->z / len; } /* Update light position hint indicating if it is above or * below the horizon (foundation of z = 0.0) */ scene->light_visibility_hint = (pos->z > 0.0f) ? 1 : 0; } /* Set scene global lighting to match sun lumination */ c = &scene->light_color; /* Scene global light color */ c->a = 1.0f; c->r = scene_lumination_coeff; c->g = scene_lumination_coeff; c->b = scene_lumination_coeff; /* Moon */ /* Move moon position based on time of day */ pos = &scene->moon_pos; /* Scene global moon position */ if(scene->tod > HTOS(12.0)) { /* Before midnight, calculate orbital position coefficient * linearly from 17:00 (coeff 0.0) to 24:00 (coeff 1.0). */ float orbital_coeff = (float)MAX( (scene->tod - HTOS(17.0)) / HTOS(7.0), 0.0 ); /* Calculate longitude aligned orbital position of light * relative to camera's xy plane. */ pos->x = (float)(cos(orbital_coeff * (0.5 * PI))); pos->y = 0.0f; /* Calculated later */ pos->z = (float)(sin(orbital_coeff * (0.5 * PI))); } else { float orbital_coeff; /* After midnight, calculate orbital position coefficient * linearly from 0:00 (coeff 1.0) to 7:00 (coeff 0.0). */ orbital_coeff = (float)(1.0 - MIN( (scene->tod - HTOS(0.0)) / HTOS(7.0), 1.0 )); /* Calculate longitude aligned orbital position of light * relative to camera's xy plane. */ pos->x = (float)(-cos(orbital_coeff * (0.5 * PI))); pos->y = 0.0f; /* Calculated later */ pos->z = (float)(sin(orbital_coeff * (0.5 * PI))); } if(1) { float lat_offset_deg = scene->dms_y_offset, lat_offset_rad, len; /* Calculate latitude offset in radians */ lat_offset_rad = (float)CLIP( DEGTORAD(lat_offset_deg), -0.5 * PI, 0.5 * PI ); pos->y = (float)(pos->y + sin(-lat_offset_rad)); /* pos->z = MAX(pos->z - sin(-lat_offset_rad), 0.0); */ /* Make into unit length */ len = (float)SFMHypot3(pos->x, pos->y, pos->z); if(len > 0.0f) { pos->x = pos->x / len; pos->y = pos->y / len; pos->z = pos->z / len; } /* Update moon position hint indicating if it is above or * below the horizon (foundation of z = 0.0) */ scene->moon_visibility_hint = (pos->z > 0.0f) ? 1 : 0; } /* Horizon */ /* Regenerate the Horizon every 5 minutes */ horizon = &scene->horizon; if(horizon->last_tod != (int)(scene->tod / (5 * 60))) { int i, total, tex_num; float rc, gc, bc; /* Coefficient color change */ float darken_coeff, midpoint = 0.88f; sar_color_struct start_color, end_color; if(opt->runtime_debug) printf( "SARSimUpdateScene(): Updating horizon textures.\n" ); /* Update last tod on the Horizon to the current time in * 5 minute units so we know when to update the Horizon * again */ horizon->last_tod = (int)(scene->tod / (5 * 60)); /* Creates a new horizon texture on the horizon */ #define DO_CREATE_TEXTURE { \ tex_num = MAX(horizon->total_textures, 0); \ horizon->total_textures = tex_num + 1; \ horizon->texture = (v3d_texture_ref_struct **)realloc( \ horizon->texture, \ horizon->total_textures * sizeof(v3d_texture_ref_struct *) \ ); \ if(horizon->texture == NULL) \ { \ horizon->total_textures = 0; \ } \ else \ { \ horizon->texture[tex_num] = SARCreateHorizonTexture( \ NULL, /* No name */ \ &start_color, &end_color, \ 32, midpoint \ ); \ } \ } /* Adjust gradient horizon textures by recreating them. * Do not add lumination/gamma to them, the light color * will be multiplied during drawing */ for(i = 0; i < horizon->total_textures; i++) V3DTextureDestroy(horizon->texture[i]); free(horizon->texture); horizon->texture = NULL; horizon->total_textures = 0; /* Create textures, starting with most brightest */ memcpy( &start_color, &scene->sky_nominal_color, sizeof(sar_color_struct) ); /* Create 7 horizon textures from order of brightest to * to darkest */ total = 7; for(i = 0; i < total; i++) { /* Calculate darken coefficient based on index of * the current horizon texture */ darken_coeff = (float)i / (float)(total - 1); /* Calculate rgb blend values from 1.0 to 2.0 */ rc = (float)MIN( (scene->sky_brighten_color.r * (1.0 - darken_coeff)) + (scene->sky_darken_color.r * darken_coeff), 1.0 ); gc = (float)MIN( (scene->sky_brighten_color.g * (1.0 - darken_coeff)) + (scene->sky_darken_color.g * darken_coeff), 1.0 ); bc = (float)MIN( (scene->sky_brighten_color.b * (1.0 - darken_coeff)) + (scene->sky_darken_color.b * darken_coeff), 1.0 ); /* Calculate end color */ end_color.a = 1.0f; end_color.r = (float)MIN( (1.0 * horizon_sat_max_coeff) + (rc * (1.0 - horizon_sat_max_coeff)), 1.0 ); end_color.g = (float)MIN( (1.0 * horizon_sat_max_coeff) + (gc * (1.0 - horizon_sat_max_coeff)), 1.0 ); end_color.b = (float)MIN( (1.0 * horizon_sat_max_coeff) + (bc * (1.0 - horizon_sat_max_coeff)), 1.0 ); DO_CREATE_TEXTURE } #undef DO_CREATE_TEXTURE } /* Cloud Billboards */ if(1) { int i; sar_cloud_bb_struct *cloud; /* Reset Primary Lightening Coeff */ scene->pri_lightening_coeff = 0.0f; /* Iterate through each Cloud Billboard */ for(i = 0; i < scene->total_cloud_bbs; i++) { cloud = scene->cloud_bb[i]; if(cloud == NULL) continue; /* Has lightening? */ if(cloud->lightening_min_int > 0) { /* Lightening currently off and waiting to go on? */ if(cloud->lightening_next_on > 0) { /* Time to go on? */ if(cloud->lightening_next_on <= cur_millitime) { const time_t ligthening_on_int = 1800l; /* Generate random lightening points */ SARSimGenerateLighteningPoints( cloud->lightening_point, SAR_LIGHTENING_POINTS_MAX, &cloud->pos, cloud->width, cloud->height ); /* Schedual next off time */ cloud->lightening_next_off = cur_millitime + ligthening_on_int; cloud->lightening_started_on = cur_millitime; cloud->lightening_next_on = 0; /* Update the Primary Lightening Coeff */ scene->pri_lightening_coeff = 1.0f; } } else { /* Time to go off? */ if(cloud->lightening_next_off <= cur_millitime) { /* Turn lightening off, play thunder sound, * and schedual next lightening on */ const time_t dt = cloud->lightening_max_int - cloud->lightening_min_int; /* If was on and now going off, then play * thunder sound */ if(cloud->lightening_next_off > 0) { switch(SARRandom(cur_millitime) % 3) { case 2: PLAY_SOUND(SAR_DEF_SOUND_THUNDER_LOUD); break; case 1: PLAY_SOUND(SAR_DEF_SOUND_THUNDER_MODERATE); break; case 0: PLAY_SOUND(SAR_DEF_SOUND_THUNDER_FAINT); break; } } /* Schedual next on time */ cloud->lightening_next_off = 0; cloud->lightening_started_on = 0; cloud->lightening_next_on = cur_millitime + cloud->lightening_min_int + (time_t)(dt * SARRandomCoeff(cur_millitime)); } else { /* Ligthening is on, update the Primary * Lightening Coeff */ const float t = (float)( cur_millitime - cloud->lightening_started_on ), dt = (float)( cloud->lightening_next_off - cloud->lightening_started_on ); const float c = (dt > 0.0f) ? (1.0f - (t / dt)) : 0.0f; if(c > scene->pri_lightening_coeff) scene->pri_lightening_coeff = c; } } } /* Has lightening? */ } } #undef HTOS return(0); } /* * First updates the timings on the scene structure's SFMRealmStruct * and then updates all objects with respect to the given scene and * core structure. * * Returns 0 on success and non-zero on error or memory pointer * change. */ int SARSimUpdateSceneObjects( sar_core_struct *core_ptr, sar_scene_struct *scene ) { int i, status; int *obj_total; sar_object_struct *obj_ptr, ***obj_pa; sar_object_aircraft_struct *obj_aircraft_ptr; sar_contact_bounds_struct *cb; SFMModelStruct *fdm; if(scene == NULL) return(-1); /* Update timing on realm */ if(scene->realm != NULL) { SFMSetTiming(scene->realm, lapsed_millitime); SFMSetTimeCompression(scene->realm, time_compression); } /* Begin handling each object on core structure */ obj_pa = &core_ptr->object; obj_total = &core_ptr->total_objects; for(i = 0; i < (*obj_total); i++) { obj_ptr = (*obj_pa)[i]; if(obj_ptr == NULL) continue; status = 0; /* Reset `SFM handled' value */ /* SFM realm structure allocated? */ if(scene->realm != NULL) { /* Handle by object type */ 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); if(obj_aircraft_ptr == NULL) break; fdm = obj_aircraft_ptr->fdm; if(fdm == NULL) break; /* Set object values to SFM structure */ SARSimSetSFMValues(core_ptr, scene, obj_ptr); /* If this is the player object then apply control * positions */ if(obj_ptr == scene->player_obj_ptr) { /* Apply player control */ SARSimApplyGCTL(core_ptr, obj_ptr); } else { /* Apply AI */ /* TODO */ } /* Set status to 1, noting that the SFM structure * was handled (which we will actually do so just * below) */ status = 1; /* Begin SFM updating */ if(SFMForceApplyArtificial(scene->realm, fdm)) break; /* Swapped, calculating natural forces after artifical gives us * more accurate center to ground height. */ if(SFMForceApplyNatural(scene->realm, fdm)) break; if(SFMForceApplyControl(scene->realm, fdm)) break; /* Get new object values from the updated SFM */ SARSimGetSFMValues(scene, obj_ptr); break; case SAR_OBJ_TYPE_GROUND: 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; } } /* Check if object survived SFM handling, in other words is * it still allocated? */ if(status) { /* SFM was handled on the object, so check if object * is still allocated. */ if(SARObjIsAllocated(*obj_pa, *obj_total, i)) obj_ptr = (*obj_pa)[i]; else continue; } /* Apply natural forces to object */ if(SARSimApplyNaturalForce(core_ptr, obj_ptr)) continue; /* Apply artificial forces to object */ if(SARSimApplyArtificialForce(core_ptr, obj_ptr)) continue; /* Get pointer to object's contact bounds structure (which * may be NULL) */ cb = obj_ptr->contact_bounds; /* Can this object crash into other objects? */ if(((cb != NULL) ? cb->crash_flags : 0) & SAR_CRASH_FLAG_CRASH_OTHER ) { /* Perform object to object crash contact check */ if(SARSimCrashContactCheck(core_ptr, obj_ptr) > -1) { /* Crash contact into another object has occured, * so we need to check if this object is still * allocated. */ if(SARObjIsAllocated(*obj_pa, *obj_total, i)) obj_ptr = (*obj_pa)[i]; else continue; } } /* Hoist deployment contact check * * If object has a hoist, its hoist deployment is out, and * an object is picked up then a valid index is returned * and the proper procedure will have been performed */ if(SARSimHoistDeploymentContactCheck(core_ptr, obj_ptr) > -1) { /* Rescue basket contact has occured, need to check if * this object is still allocated */ if(SARObjIsAllocated(*obj_pa, *obj_total, i)) obj_ptr = (*obj_pa)[i]; else continue; } /* Check if the object is "too old", if it is then it * will be deleted */ if(SARSimDoMortality(core_ptr, obj_ptr)) { /* Object has been deleted, check if it is still * allocated (which it probably won't be). */ if(SARObjIsAllocated(*obj_pa, *obj_total, i)) obj_ptr = (*obj_pa)[i]; else continue; } /* Add more object updates here */ } return(0); } searchandrescue_1.5.0/sar/sarmusic.c0000644000175000017500000002451510104532751016526 0ustar jessejesse#include #include #include #include #include #include "../include/string.h" #include "../include/disk.h" #include "sound.h" #include "menu.h" #include "obj.h" #include "objutils.h" #include "sar.h" #include "sarmusic.h" #include "sarmenucodes.h" #include "config.h" void SARMusicUpdate(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))) /* * Checks the current situation (current music, current menu or * simulation, player object state, etc) and changes the music * as needed. * * This function should be called once per loop or whenever the * music is suspected to need to be changed. * * The global opt->music state will be checked and music will * be turned on or off as needed. */ void SARMusicUpdate(sar_core_struct *core_ptr) { int prev_id, new_id, new_enter_id; sar_menu_struct *cur_menu_ptr; snd_recorder_struct *recorder = core_ptr->recorder; sar_option_struct *opt = &core_ptr->option; if(recorder == NULL) return; /* Get current music id (can be -1) and record it as the * previous music id */ prev_id = core_ptr->cur_music_id; /* Is music state switched on in the options? */ if(opt->music) { } else { /* Music is suppose to be off, so turn it off as needed * and return */ if(SoundMusicIsPlaying(recorder)) SoundMusicStopPlay(recorder); return; } /* ******************************************************** */ /* Begin checking which music id should be played, for * `repeating' and `enter' styles. After this check, new_id * and new_enter_id will be updated to the id codes of the * songs intended to be played */ new_id = -1; new_enter_id = -1; /* First determine if we are in the menu system or in * simulation * * The appropriate new music ids should be choosen (if any) * here */ cur_menu_ptr = SARGetCurrentMenuPtr(core_ptr); if(cur_menu_ptr != NULL) { /* In menu system, choose new music ids by checking * which menu we are currently in (check the current * menu's name) */ const char *menu_name = (const char *)cur_menu_ptr->name; if(menu_name != NULL) { /* Loading simulation menu? */ if(!strcasecmp(menu_name, SAR_MENU_NAME_LOADING_SIMULATION)) { new_id = SAR_MUSIC_ID_LOADING_SIMULATION; } /* Main menu? */ else if(!strcasecmp(menu_name, SAR_MENU_NAME_MAIN)) { new_id = SAR_MUSIC_ID_MENUS; } /* TODO Add code to check other menus here */ else { /* Some other menu, use the generic menu music id */ new_id = SAR_MUSIC_ID_MENUS; } } else { /* No menu name available, just use the generic menu * music id then */ new_id = SAR_MUSIC_ID_MENUS; } } /* In menu system? */ else { /* Not in menu system, probably in simulation. Check * the state of the scene and player object to choose * the appropriate music id */ sar_scene_struct *scene = core_ptr->scene; sar_object_struct *obj_ptr = NULL; /* Scene structure must be available */ if(scene != NULL) { /* Get the pointer to the player object, the state * of the player object will dictate which music * id will be choosen. */ obj_ptr = scene->player_obj_ptr; /* Player object exists? */ if(obj_ptr != NULL) { sar_object_aircraft_struct *obj_aircraft_ptr; sar_obj_hoist_struct *hoist_ptr; /* Get pointers to object's substructures */ obj_aircraft_ptr = SAR_OBJ_GET_AIRCRAFT(obj_ptr); hoist_ptr = SARObjGetHoistPtr(obj_ptr, 0, NULL); /* Begin checking by player object type and its * status to determine the new music id's */ if(obj_aircraft_ptr != NULL) { if(obj_aircraft_ptr->landed) { new_id = SAR_MUSIC_ID_SIMULATION_ONGROUND; new_enter_id = SAR_MUSIC_ID_SIMULATION_ONGROUND_ENTER; } else { /* In flight */ switch(scene->tod_code) { case SAR_TOD_CODE_NIGHT: new_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_NIGHT; new_enter_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_NIGHT_ENTER; break; case SAR_TOD_CODE_DUSK: case SAR_TOD_CODE_DAWN: case SAR_TOD_CODE_DAY: case SAR_TOD_CODE_UNDEFINED: new_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_DAY; new_enter_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_DAY_ENTER; break; } } } if(hoist_ptr != NULL) { if(hoist_ptr->rope_cur > 0.0) { new_id = SAR_MUSIC_ID_SIMULATION_RESCUE; new_enter_id = SAR_MUSIC_ID_SIMULATION_RESCUE_ENTER; } } /* Set music id's to defaults if they were not able * to be determined above. */ if(new_id < 0) new_id = SAR_MUSIC_ID_SIMULATION_ONGROUND; if(new_enter_id < 0) new_enter_id = SAR_MUSIC_ID_SIMULATION_ONGROUND_ENTER; } else { /* No player object available, assume on ground */ new_id = SAR_MUSIC_ID_SIMULATION_ONGROUND; new_enter_id = SAR_MUSIC_ID_SIMULATION_ONGROUND_ENTER; } } } /* In simulation */ /* ******************************************************** */ /* At this point the new music id's should have been * choosen, they can still be -1 to indicate no change. */ /* Macro to return the music reference file as tmp_path from the * given music_ref_ptr. Uses variables tmp_path[PATH_MAX + NAME_MAX] * and music_ref_ptr. */ #define GET_MUSIC_REF_FILE \ { \ *tmp_path = '\0'; \ if((music_ref_ptr != NULL) ? (music_ref_ptr->filename != NULL) : 0) \ { \ struct stat stat_buf; \ const char *cstrptr = PrefixPaths( \ dname.local_data, music_ref_ptr->filename \ ); \ /* Check local file to see if it exists first */ \ if((cstrptr != NULL) ? !stat(cstrptr, &stat_buf) : 0) \ { \ /* Found local file, put that path value in tmp_path */ \ strncpy(tmp_path, cstrptr, PATH_MAX + NAME_MAX); \ } \ else \ { \ /* Check global file */ \ cstrptr = PrefixPaths( \ dname.global_data, music_ref_ptr->filename \ ); \ if((cstrptr != NULL) ? !stat(cstrptr, &stat_buf) : 0) \ { \ /* Found global file, put that path value in tmp_path */ \ strncpy(tmp_path, cstrptr, PATH_MAX + NAME_MAX); \ } \ } \ } \ } /* Change in music id's and new music id is valid? */ if((new_id != prev_id) && (new_id > -1)) { int music_ref_num; sar_music_ref_struct *music_ref_ptr; char tmp_path[PATH_MAX + NAME_MAX]; if(opt->runtime_debug) printf( "SARMusicUpdate(): Changing to music id %i from id %i\n", new_id, prev_id ); /* Find music reference in list that matches the music id * specified by new_id. */ music_ref_ptr = SARMusicMatchPtr( core_ptr->music_ref, core_ptr->total_music_refs, new_id, &music_ref_num ); /* Found music reference matching new_id? */ if(music_ref_ptr != NULL) { /* Stop playing previous music (if any) and start * playing the new one. */ GET_MUSIC_REF_FILE if(SoundMusicStartPlay( recorder, tmp_path, (music_ref_ptr->flags & SAR_MUSIC_REF_FLAGS_REPEAT) ? -1 : 1 )) { /* Error playing this music, need to print warning * and switch off music. */ fprintf( stderr, "%s: Unable to play music, turning music off.\n", music_ref_ptr->filename ); opt->music = False; core_ptr->cur_music_id = prev_id = new_id = -1; } else { /* Successfully started playing new music, update * current music id. */ core_ptr->cur_music_id = prev_id = new_id; } } else { /* No music reference for the given id, continue playing * previous music and do not update current music id. */ } } /* No change in music id's and new music id is valid? */ else if(new_id > -1) { /* No change in music id, but need to check if music is * still playing. If it not playing then it needs to be * either restarted or changed to the next consecutive * song. */ if(!SoundMusicIsPlaying(recorder)) { int music_ref_num; sar_music_ref_struct *music_ref_ptr; char tmp_path[PATH_MAX + NAME_MAX]; if(opt->runtime_debug) printf( "SARMusicUpdate(): Music id %i has stopped playing.\n", new_id ); /* Update new_id to the `next' song that needs to be * played after the current one has stopped. */ switch(prev_id) { case SAR_MUSIC_ID_SIMULATION_ONGROUND_ENTER: new_id = SAR_MUSIC_ID_SIMULATION_ONGROUND; break; case SAR_MUSIC_ID_SIMULATION_INFLIGHT_DAY_ENTER: new_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_DAY; break; case SAR_MUSIC_ID_SIMULATION_INFLIGHT_NIGHT_ENTER: new_id = SAR_MUSIC_ID_SIMULATION_INFLIGHT_NIGHT; break; case SAR_MUSIC_ID_SIMULATION_RESCUE_ENTER: new_id = SAR_MUSIC_ID_SIMULATION_RESCUE; break; default: /* All other music id's when stopped should just * re-start as the same music id. */ new_id = prev_id; break; } if(opt->runtime_debug) printf( "SARMusicUpdate(): Previous music id %i stopped, playing new music id %i.\n", prev_id, new_id ); /* Find music reference in list that matches the music * id specified by new_id. */ music_ref_ptr = SARMusicMatchPtr( core_ptr->music_ref, core_ptr->total_music_refs, new_id, &music_ref_num ); /* Found music reference matching new_id? */ if(music_ref_ptr != NULL) { /* Start playing new music */ GET_MUSIC_REF_FILE if(SoundMusicStartPlay( recorder, tmp_path, (music_ref_ptr->flags & SAR_MUSIC_REF_FLAGS_REPEAT) ? -1 : 1 )) { /* Error playing this music, need to print warning * and switch off music. */ fprintf( stderr, "%s: Unable to play music, turning music off.\n", music_ref_ptr->filename ); opt->music = False; core_ptr->cur_music_id = prev_id = new_id = -1; } else { /* Successfully started playing new music, update * current music id. */ core_ptr->cur_music_id = prev_id = new_id; } } else { /* No music reference for the given id or music needs * to stop until changed. So do not update the current * music id (even if the previous music has stopped). */ } } /* Music has stopped playing? */ } #undef GET_MUSIC_REF_FILE } searchandrescue_1.5.0/sar/explosion.h0000644000175000017500000000117010104532746016721 0ustar jessejesse/* * Explosion & Splash Creation */ #ifndef EXPLOSION_H #define EXPLOSION_H #include "obj.h" #include "sar.h" extern int ExplosionCreate( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, const sar_position_struct *pos, float radius, int ref_object, const char *tex_name, const char *ir_tex_name ); extern int SplashCreate( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, const sar_position_struct *pos, float radius, int ref_object, const char *tex_name, const char *ir_tex_name ); #endif /* EXPLOSION_H */ searchandrescue_1.5.0/sar/weatherio.c0000644000175000017500000002501010104532752016657 0ustar jessejesse#include #include #include #include #include #include #include #include "../include/fio.h" #include "../include/disk.h" #include "../include/string.h" #include "obj.h" #include "weather.h" #include "config.h" int SARWeatherLoadFromFile( sar_weather_data_struct *w, const char *filename ); #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))) /* * Loads weather presets list from file. */ int SARWeatherLoadFromFile( sar_weather_data_struct *w, const char *filename ) { int i; FILE *fp; char *buf = NULL; struct stat stat_buf; sar_weather_data_struct *wd = w; sar_weather_data_entry_struct *wdp_ptr = NULL; sar_color_struct *color_ptr = NULL; sar_cloud_layer_struct *cloud_layer_ptr = NULL; sar_cloud_bb_struct *cloud_bb_ptr = NULL; double value[10]; if((filename == NULL) || (wd == NULL)) return(-1); /* Delete any existing preset weather data entries */ for(i = 0; i < wd->total_presets; i++) SARWeatherEntryDelete( wd, wd->preset[i] ); /* 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); } #ifdef S_ISDIR if(S_ISDIR(stat_buf.st_mode)) { fprintf( stderr, "%s: Is a directory.\n", filename ); return(-1); } #endif /* S_ISDIR */ /* Open weather presets file for reading */ fp = FOpen(filename, "rb"); if(fp == NULL) { fprintf( stderr, "%s: Unable to open the Weather Presets file for reading.\n", filename ); return(-1); } #define DO_SET_COLOR { \ if(color_ptr != NULL) { \ color_ptr->r = (float)value[0]; \ color_ptr->g = (float)value[1]; \ color_ptr->b = (float)value[2]; \ color_ptr->a = (float)value[3]; \ } \ } do { buf = FSeekNextParm( fp, buf, SAR_COMMENT_CHAR, SAR_CFG_DELIM_CHAR ); if(buf == NULL) break; /* Begin handling parameter */ /* Version? */ if(!strcasecmp(buf, "Version")) { FGetValuesF(fp, value, 2); /* Ignore */ } /* Add a new preset weather data entry? */ else if(!strcasecmp(buf, "PresetAdd")) { char *strptr = FGetString(fp); wdp_ptr = NULL; /* Allocate a new pointer and structure */ i = wd->total_presets; wd->total_presets++; wd->preset = (sar_weather_data_entry_struct **)realloc( wd->preset, wd->total_presets * sizeof(sar_weather_data_entry_struct *) ); if(wd->preset == NULL) { wd->total_presets = 0; } else { wdp_ptr = (sar_weather_data_entry_struct *)calloc( 1, sizeof(sar_weather_data_entry_struct) ); wd->preset[i] = wdp_ptr; } /* Set perset name */ if(wdp_ptr != NULL) wdp_ptr->name = strptr; else free(strptr); } /* Sky color nominal */ else if(!strcasecmp(buf, "ColorSkyNominal")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sky_nominal_color; DO_SET_COLOR } } /* Sky color brighten */ else if(!strcasecmp(buf, "ColorSkyBrighten")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sky_brighten_color; DO_SET_COLOR } } /* Sky color darken */ else if(!strcasecmp(buf, "ColorSkyDarken")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sky_darken_color; DO_SET_COLOR } } /* Color of stars */ else if(!strcasecmp(buf, "ColorStarLow")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->star_low_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorStarHigh")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->star_high_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorStar")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->star_low_color; DO_SET_COLOR color_ptr = &wdp_ptr->star_high_color; DO_SET_COLOR } } /* Color of sun */ else if(!strcasecmp(buf, "ColorSunLow")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sun_low_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorSunHigh")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sun_high_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorSun")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->sun_low_color; DO_SET_COLOR color_ptr = &wdp_ptr->sun_high_color; DO_SET_COLOR } } /* Color of moon */ else if(!strcasecmp(buf, "ColorMoonLow")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->moon_low_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorMoonHigh")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->moon_high_color; DO_SET_COLOR } } else if(!strcasecmp(buf, "ColorMoon")) { FGetValuesF(fp, value, 4); if(wdp_ptr != NULL) { color_ptr = &wdp_ptr->moon_low_color; DO_SET_COLOR color_ptr = &wdp_ptr->moon_high_color; DO_SET_COLOR } } /* Atmosphere distance coefficient (from far to near) */ else if(!strcasecmp(buf, "AtmosphereDistanceCoefficient") || !strcasecmp(buf, "AtmosphereDistanceCoeff") ) { FGetValuesF(fp, value, 1); if(wdp_ptr != NULL) wdp_ptr->atmosphere_dist_coeff = (float)value[0]; } /* Atmosphere density coefficient */ else if(!strcasecmp(buf, "AtmosphereDensityCoefficient") || !strcasecmp(buf, "AtmosphereDensityCoeff") ) { FGetValuesF(fp, value, 1); if(wdp_ptr != NULL) wdp_ptr->atmosphere_density_coeff = (float)value[0]; } /* Rain density */ else if(!strcasecmp(buf, "RainDensityCoefficient") || !strcasecmp(buf, "RainDensityCoeff") ) { FGetValuesF(fp, value, 1); if(wdp_ptr != NULL) wdp_ptr->rain_density_coeff = (float)value[0]; } /* Add a new cloud layer? */ else if(!strcasecmp(buf, "CloudLayerAdd")) { FSeekNextLine(fp); /* No arguments */ cloud_layer_ptr = NULL; /* Reset */ if(wdp_ptr != NULL) { /* Allocate a new cloud layer */ i = wdp_ptr->total_cloud_layers; wdp_ptr->total_cloud_layers++; wdp_ptr->cloud_layer = (sar_cloud_layer_struct **)realloc( wdp_ptr->cloud_layer, wdp_ptr->total_cloud_layers * sizeof(sar_cloud_layer_struct *) ); if(wdp_ptr->cloud_layer == NULL) { wdp_ptr->total_cloud_layers = 0; } else { cloud_layer_ptr = (sar_cloud_layer_struct *)calloc( 1, sizeof(sar_cloud_layer_struct) ); wdp_ptr->cloud_layer[i] = cloud_layer_ptr; } } } else if(!strcasecmp(buf, "CloudLayerSize")) { FGetValuesF(fp, value, 2); if(cloud_layer_ptr != NULL) { cloud_layer_ptr->tile_width = MAX((int)value[0], 100); cloud_layer_ptr->tile_height = MAX((int)value[1], 100); } } else if(!strcasecmp(buf, "CloudLayerRange")) { FGetValuesF(fp, value, 1); if(cloud_layer_ptr != NULL) cloud_layer_ptr->range = (float)MAX(value[0], 100.0); } else if(!strcasecmp(buf, "CloudLayerAltitude")) { FGetValuesF(fp, value, 1); if(cloud_layer_ptr != NULL) cloud_layer_ptr->z = (float)SFMFeetToMeters(value[0]); } else if(!strcasecmp(buf, "CloudLayerTexture")) { char *strptr = FGetString(fp); if(strptr != NULL) { if(cloud_layer_ptr != NULL) { free(cloud_layer_ptr->tex_name); cloud_layer_ptr->tex_name = strptr; } else { free(strptr); } } } /* Add a new cloud `billboard' object? */ else if(!strcasecmp(buf, "CloudBBAdd") || !strcasecmp(buf, "CloudBillboardAdd") || !strcasecmp(buf, "CloudBillBoardAdd") ) { FSeekNextLine(fp); /* No arguments */ cloud_bb_ptr = NULL; /* Reset */ if(wdp_ptr != NULL) { /* Allocate a new cloud `billboard' object */ i = wdp_ptr->total_cloud_bbs; wdp_ptr->total_cloud_bbs++; wdp_ptr->cloud_bb = (sar_cloud_bb_struct **)realloc( wdp_ptr->cloud_bb, wdp_ptr->total_cloud_bbs * sizeof(sar_cloud_bb_struct *) ); if(wdp_ptr->cloud_bb == NULL) { wdp_ptr->total_cloud_bbs = 0; } else { cloud_bb_ptr = (sar_cloud_bb_struct *)calloc( 1, sizeof(sar_cloud_bb_struct) ); wdp_ptr->cloud_bb[i] = cloud_bb_ptr; } } } else if(!strcasecmp(buf, "CloudBBSize")) { FGetValuesF(fp, value, 4); if(cloud_bb_ptr != NULL) { cloud_bb_ptr->tile_width = (int)MAX(value[0], 100); cloud_bb_ptr->tile_height = (int)MAX(value[1], 100); cloud_bb_ptr->width = (float)MAX(value[2], 100); cloud_bb_ptr->height = (float)MAX(value[3], 100); } } else if(!strcasecmp(buf, "CloudBBOffset")) { FGetValuesF(fp, value, 3); if(cloud_bb_ptr != NULL) { sar_position_struct *pos = &cloud_bb_ptr->pos; pos->x = (float)value[0]; pos->y = (float)value[1]; pos->z = (float)value[2]; } } else if(!strcasecmp(buf, "CloudBBTexture")) { char *s = FGetString(fp); if(s != NULL) { if(cloud_bb_ptr != NULL) { free(cloud_bb_ptr->tex_name); cloud_bb_ptr->tex_name = s; } else { free(s); } } } else if(!strcasecmp(buf, "CloudBBLighteningInterval") || !strcasecmp(buf, "CloudBBLighteningInt") ) { FGetValuesF(fp, value, 2); if(cloud_bb_ptr != NULL) { cloud_bb_ptr->lightening_min_int = (time_t)value[0]; cloud_bb_ptr->lightening_max_int = (time_t)value[1]; } } else { fprintf( stderr, "%s: Unsupported parameter \"%s\".\n", filename, buf ); FSeekNextLine(fp); } } while(1); free(buf); /* Close weather file */ FClose(fp); return(0); } searchandrescue_1.5.0/sar/man/0000755000175000017500000000000011364653106015307 5ustar jessejessesearchandrescue_1.5.0/sar/man/SearchAndRescue.6.bz20000644000175000017500000000647211364653052021102 0ustar jessejesseBZh91AY&SYU_]w?`}-u)|ץ\kӳ[řā&&"zSڦzaMFz@i'44ёp # !@2adɄ`!'O6)ڍ #&C@z U=G 4ɑ44 M&CA=!=I?T~4l(4=M45+c6NϮ?/_hUYHK&wȃH?^FFWRi66e4 hc9랖›Yn_r@˝%@Nt? roAp A$I"#ϧ&yƦ89FUbt;S 0rv7.+!=ͳڎ,,>M4zO{ -1)o ?'~ ޾YQw P¬eC`yR hgmeVS܊X}_)N[$u6}=鮃;3N.t  XjnACyťMEvCGUJ:w=: d(=dq^we@6VB@rᢦR8Wn)e3Tar G`q&: I\Fy]v]h[{~oARJX 挢ޫWUl^Yq;͎it'|I }''t=_|zxiV[C$塷+)4 _Z `D>}fP>1 j *bRtҐˑO<-DRke>spVܶ(M0h2H- _< w;xHH j5CE-hxoc f[40с&~]$!,?T=yWHA7@YGh;uQeMP uvWSWU;80ˆ<1JwXY !*0@!+V[Am{ vLG1ƹ2](t\Ymb"481(6,z d$DǍ( #7AۄGx3⫖ǯV8 А()gV!@q;oĦeCQ pK\x3mYkiAM& kŦw\ %fZ圥KjA#GY7E8򿺇l\࡙Z~&ٹ3i6ԐC@{?UJg{:\|M,&V7 7@e4H#Rd"n춵z}бʨ"FuС_w:-/H50B6bQ&KȺ$*9-kƎѤp X?FAg]Z%֕LZƐ&t +* wV8v ̄*8M Z~1MhN>4`{l:?HT1%Ѣ翇|EGt,hb-@ p\<~BN> cF"cU^/vؖXNavk3%af h^uQn\;bz\yn7\xm1o RKKa[4v0By2\\3n sIy'~;j*T 'pL9HDOtAA0=kdVԚz 7e8AtLX&TH93%IM[Py9зm`Qf2WAϽ%;:Η+(sk!T84 v̀&)c{44%^BߔfO uP%(hg֘>7Z7bem kx֋V@!mÀ^QUE1C╀{ ;% lc{%xۻJckm5jTVd0k0Ʊ:S-`dE+)W*цط LhcxcT/,;e5E6XFk`bfV,Ivf5F wA+@,T{݉m+=6$jRkZp UA@x(ߌ8$$eu*r2C%R-@4I-Y) IARA4_p7[Q佨($@ᨈq.0)㪩aqce(l?6YQhtM5O{e>46׽2PrEu.l؛v iiKˬ <:K,z5xG RA{Z*9PV!b78ʢ֡߸_]BB;"searchandrescue_1.5.0/sar/stategl.h0000644000175000017500000000714410104532752016350 0ustar jessejesse/* OpenGL State Recording Functions to keep track of OpenGL states. */ #ifndef STATEGL_H #define STATEGL_H #ifdef __MSW__ # include # include #endif #ifndef True # define True 1 #endif #ifndef False # define False 0 #endif #define StateGLBoolean unsigned char /* * GL state record struct: * * When adding new states to this structure, be sure to update * function SARGLStateResetAll(), StateGLEnable(), and * StateGLDisable() to handle it * * Plus create any additional functions to set specific function * parameters */ typedef struct { /* Boolean values for each supported states */ StateGLBoolean alpha_test, blend, color_material, cull_face, depth_test, dither, fog, lighting, light0, light1, light2, light3, light4, light5, light6, light7, line_smooth, point_smooth, polygon_offset_fill, polygon_offset_line, polygon_offset_point, scissor_test, stencil_test, texture_1d, texture_2d, texture_3d, write_unbiased_depth; /* Alpha function state */ GLenum alpha_func_func; GLclampf alpha_func_ref; /* Blend function state */ GLenum blend_func_sfactor, blend_func_dfactor; /* Color material parameters */ GLenum color_material_face, color_material_mode; /* Depth test function state */ GLenum depth_func_func; /* Depth buffer writing (GL_TRUE to enable) */ GLboolean depth_mask_flag; /* Front face cull winding */ GLenum front_face_mode; /* Line width */ GLfloat line_width; /* Point size */ GLfloat point_size; /* Polygon offset */ GLfloat polygon_offset_factor, polygon_offset_units; /* Scissor test */ GLint scissor_test_x, scissor_test_y; GLsizei scissor_test_width, scissor_test_height; /* Shade model */ GLenum shade_model_mode; /* Stencil function */ GLenum stencil_func_func; GLint stencil_func_ref; GLuint stencil_func_mask; /* Stencil operation */ GLenum stencil_op_fail, stencil_op_zfail, stencil_op_zpass; /* Texture enviroment state */ GLenum tex_env_target, tex_env_pname; GLint tex_env_param; } state_gl_struct; #define STATE_GL(p) ((state_gl_struct *)(p)) extern void StateGLEnableF(state_gl_struct *s, GLenum cap, GLboolean force); extern void StateGLEnable(state_gl_struct *s, GLenum cap); extern void StateGLDisableF(state_gl_struct *s, GLenum cap, GLboolean force); extern void StateGLDisable(state_gl_struct *s, GLenum cap); extern void StateGLAlphaFunc( state_gl_struct *s, GLenum func, GLclampf ref ); extern void StateGLBlendFunc( state_gl_struct *s, GLenum sfactor, GLenum dfactor ); extern void StateGLColorMaterial( state_gl_struct *s, GLenum face, GLenum mode ); extern void StateGLDepthFunc( state_gl_struct *s, GLenum func ); extern void StateGLDepthMask( state_gl_struct *s, GLboolean flag ); extern void StateGLFrontFace( state_gl_struct *s, GLenum mode ); extern void StateGLLineWidth( state_gl_struct *s, GLfloat width ); extern void StateGLPointSize( state_gl_struct *s, GLfloat size ); extern void StateGLPolygonOffset( state_gl_struct *s, GLfloat factor, GLfloat units ); extern void StateGLScissor( state_gl_struct *s, GLint x, GLint y, GLsizei width, GLsizei height ); extern void StateGLShadeModel( state_gl_struct *s, GLenum mode ); extern void StateGLStencilFunc( state_gl_struct *s, GLenum func, GLint ref, GLuint mask ); extern void StateGLStencilOp( state_gl_struct *s, GLenum fail, GLenum zfail, GLenum zpass ); extern void StateGLTexEnvI( state_gl_struct *s, GLenum target, GLenum pname, GLint param ); extern void StateGLResetAll(state_gl_struct *s); #endif /* STATEGL_H */ searchandrescue_1.5.0/sar/simcb.c0000644000175000017500000011545411552633645016014 0ustar jessejesse#include #include #include #include #include #include "matrixmath.h" #include "sfm.h" #include "obj.h" #include "objutils.h" #include "objsound.h" #include "messages.h" #include "smoke.h" #include "explosion.h" #include "sar.h" #include "simmanage.h" #include "simcb.h" #include "simop.h" #include "simutils.h" #include "sardrawselect.h" #include "config.h" void SARSimInitModelCB( void *realm_ptr, SFMModelStruct *model, void *client_data ); void SARSimDestroyModelCB( void *realm_ptr, SFMModelStruct *model, void *client_data ); void SARSimAirborneCB( void *realm_ptr, SFMModelStruct *model, void *client_data ); void SARSimTouchDownCB( void *realm_ptr, SFMModelStruct *model, void *client_data, double impact_coeff ); void SARSimOverspeedCB( void *realm_ptr, SFMModelStruct *model, void *client_data, double cur_speed, double overspeed_expected, double overspeed ); void SARSimCollisionCB( void *realm_ptr, SFMModelStruct *model, SFMModelStruct *obstruction, void *client_data, double impact_coeff ); void SARSimObjectCollisionCB( void *client_data, /* Core structure */ sar_object_struct *obj_ptr, sar_object_struct *obstruction_obj_ptr, double impact_coeff ); #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) /* * FDM Initialize callback * * Sets up initial values from the model's corresponding object. */ void SARSimInitModelCB( void *realm_ptr, SFMModelStruct *model, void *client_data ) { int obj_num; sar_object_struct *obj_ptr; SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; /* Match object from FDM */ obj_ptr = SARSimMatchObjectFromFDM( core_ptr->object, core_ptr->total_objects, model, &obj_num ); if(obj_ptr == NULL) return; /* Set up initial values, note that position and direction * values will probably be reset soon afterwards since * creation of FDM's usually happen in the middle of * scene file parsings and their positions will be * set after creation of the FDM */ #if 0 /* No need to set position of model, calling function should do that */ model->position.x = obj_ptr->pos.x; model->position.y = obj_ptr->pos.y; model->position.z = obj_ptr->pos.z; model->direction.heading = obj_ptr->dir.heading; model->direction.pitch = obj_ptr->dir.pitch; model->direction.bank = obj_ptr->dir.bank; #endif /* Always assume landed */ model->landed_state = True; } /* * FDM Destroy callback. * * Note that the specified FDM is invalid and should not be * referenced. */ void SARSimDestroyModelCB( void *realm_ptr, SFMModelStruct *model, void *client_data ) { int i; sar_object_struct *obj_ptr; sar_object_aircraft_struct *obj_aircraft_ptr; SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; /* Iterate through objects and unset FDM references to the * specified FDM */ for(i = 0; i < core_ptr->total_objects; i++) { obj_ptr = core_ptr->object[i]; if(obj_ptr == NULL) continue; 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); if(obj_aircraft_ptr == NULL) break; if(obj_aircraft_ptr->fdm == model) obj_aircraft_ptr->fdm = NULL; break; case SAR_OBJ_TYPE_GROUND: 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; } } } /* * FDM Airborne callback. * * Called whenever the FDM just leaves the ground. */ void SARSimAirborneCB( void *realm_ptr, SFMModelStruct *model, void *client_data ) { SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; #if 0 /* Skip airborne check entirly if in slew mode */ if(SARSimIsSlew(obj_ptr)) return; #endif } /* * FDM Touchdown callback. * * Called whenever the FDM just lands (on any surface). */ void SARSimTouchDownCB( void *realm_ptr, SFMModelStruct *model, void *client_data, double impact_coeff ) { int obj_num, *gcc_list, gcc_list_total, crash_cause = 0; Boolean over_water = False, have_floats = False, camera_in_cockpit = False; float distance_to_camera, contact_radius = 0.0f; sar_obj_flags_t crash_flags = 0; sar_air_worthy_state air_worthy_state = SAR_AIR_WORTHY_FLYABLE; sar_position_struct *pos, *ear_pos, *vel = NULL; sar_direction_struct *dir; sar_contact_bounds_struct *cb; sar_object_struct *obj_ptr; sar_object_aircraft_struct *obj_aircraft_ptr = NULL; sar_scene_struct *scene; SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); const sar_option_struct *opt; if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; opt = &core_ptr->option; scene = core_ptr->scene; if(scene == NULL) return; /* Creates sparks and plays the landed on belly sound */ #define DO_EFFECTS_LAND_BELLY \ { if((obj_aircraft_ptr != NULL) && (cb != NULL)) { \ const time_t life_span = 5000l; \ sar_position_struct pos_offset; \ pos_offset.x = 0.0f; \ pos_offset.y = 0.0f; \ pos_offset.z = -obj_aircraft_ptr->belly_height; \ /* Create sparks */ \ SmokeCreateSparks( \ scene, &core_ptr->object, &core_ptr->total_objects, \ &obj_ptr->pos, &pos_offset, \ cb->contact_radius * 2.0f, \ obj_num, \ cur_millitime + life_span \ ); \ } \ /* Play sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_belly_inside" : "land_belly", \ pos, dir, ear_pos \ ); \ } /* Plays landed on skis with minimal scraping sound */ #define DO_EFFECTS_LAND_SKIS \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_ski_inside" : "land_ski", \ pos, dir, ear_pos \ ); \ } /* Creates sparks and play landed on skis with hard scraping sound */ #define DO_EFFECTS_LAND_SKIS_SKID \ { if((obj_aircraft_ptr != NULL) && (cb != NULL)) { \ const time_t life_span = 4000l; \ sar_position_struct pos_offset; \ pos_offset.x = 0.0f; \ pos_offset.y = 0.0f; \ pos_offset.z = (float)-( \ obj_aircraft_ptr->belly_height + \ obj_aircraft_ptr->gear_height \ ); \ /* Create sparks */ \ SmokeCreateSparks( \ scene, &core_ptr->object, &core_ptr->total_objects, \ &obj_ptr->pos, &pos_offset, \ cb->contact_radius * 2.0f, \ obj_num, \ cur_millitime + life_span \ ); \ } \ /* Play Sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_ski_skid_inside" : "land_ski_skid", \ pos, dir, ear_pos \ ); \ } /* Creates smoke puffs at each landing gear and plays the wheel skid * sound */ #define DO_EFFECTS_LAND_WHEEL_SKID \ { if(obj_aircraft_ptr != NULL) { \ const time_t life_span = 3500l; \ int i; \ sar_obj_part_struct *part; \ for(i = 0; True; i++) { \ part = SARObjGetPartPtr( \ obj_ptr, SAR_OBJ_PART_TYPE_LANDING_GEAR, i \ ); \ if(part == NULL) \ break; \ /* Create smoke puff at this landing gear */ \ SmokeCreate( \ scene, &core_ptr->object, &core_ptr->total_objects, \ SAR_SMOKE_TYPE_SMOKE, \ &obj_ptr->pos, &part->pos_max, \ 0.25f, 1.5f,/* Radius min and max */ \ -1.0f, /* Autocalc growth */ \ 1, /* Hide at max? */ \ 1, /* Total units */ \ life_span, /* Respawn interval in ms */ \ SAR_STD_TEXNAME_SMOKE_LIGHT, \ -1, /* No reference object */ \ cur_millitime + life_span \ ); \ } \ } \ /* Play sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_wheel_skid_inside" : "land_wheel_skid", \ pos, dir, ear_pos \ ); \ } /* Plays the crash on ground sound */ #define DO_EFFECTS_CRASH_GROUND \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ scene->sndsrc, scene->total_sndsrcs, \ "crash_ground", \ pos, dir, ear_pos \ ); \ } /* Plays the splash on water sound */ #define DO_EFFECTS_SPLASH_AIRCRAFT \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ scene->sndsrc, scene->total_sndsrcs, \ "splash_aircraft", \ pos, dir, ear_pos \ ); \ } /* Match object from FDM */ obj_ptr = SARSimMatchObjectFromFDM( core_ptr->object, core_ptr->total_objects, model, &obj_num ); if(obj_ptr == NULL) return; /* Skip touch down check entirly if in slew mode */ if(SARSimIsSlew(obj_ptr)) return; /* Get list of objects at this object's position */ gcc_list = SARGetGCCHitList( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, &gcc_list_total ); /* Check if this object landed over water */ SARGetGHCOverWater( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, NULL, &over_water ); /* Get up to date object position from the FDM */ pos = &obj_ptr->pos; pos->x = (float)model->position.x; pos->y = (float)model->position.y; pos->z = (float)model->position.z; ear_pos = &scene->ear_pos; /* Get up to date object direction from the FDM */ dir = &obj_ptr->dir; dir->heading = (float)model->direction.heading; dir->pitch = (float)model->direction.pitch; dir->bank = (float)model->direction.bank; /* Get contact bounds */ cb = obj_ptr->contact_bounds; if(cb != NULL) { crash_flags = cb->crash_flags; contact_radius = SARSimGetFlatContactRadius(obj_ptr); } /* Calculate distance between the object and the camera/ear */ distance_to_camera = (float)SFMHypot3( pos->x - ear_pos->x, pos->y - ear_pos->y, pos->z - ear_pos->z ); /* Check if camera is inside the cockpit */ switch(scene->camera_ref) { case SAR_CAMERA_REF_COCKPIT: camera_in_cockpit = True; break; case SAR_CAMERA_REF_SPOT: case SAR_CAMERA_REF_TOWER: case SAR_CAMERA_REF_MAP: case SAR_CAMERA_REF_HOIST: break; } /* Get object type specific values */ 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); if(obj_aircraft_ptr != NULL) { int i; const sar_obj_part_struct *gear; vel = &obj_aircraft_ptr->vel; vel->x = (float)model->velocity_vector.x; vel->y = (float)model->velocity_vector.y; vel->z = (float)model->velocity_vector.z; air_worthy_state = obj_aircraft_ptr->air_worthy_state; /* Check if this object has floats */ for(i = 0; True; i++) { gear = SARObjGetPartPtr( obj_ptr, SAR_OBJ_PART_TYPE_LANDING_GEAR, i ); if(gear == NULL) break; if(gear->flags & SAR_OBJ_PART_FLAG_LGEAR_FLOATS) have_floats = True; } } break; case SAR_OBJ_TYPE_GROUND: 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; } /* Substructure data pointer should now be set */ /* Values for crash_cause are: * * 5 Hit ground but was not flyable * 4 Splash * 3 Hit ground but was out of control * 2 Landed at bad angle * 1 Hit ground too hard * 0 No crash */ /* If object was already in flight but was not flyable * (ie it hit a building and is falling to the ground), * then contacting the ground is a crash. */ if(air_worthy_state == SAR_AIR_WORTHY_NOT_FLYABLE) { /* Already crashed and is considered a pile of junk */ crash_cause = 5; } else if(air_worthy_state == SAR_AIR_WORTHY_OUT_OF_CONTROL) { /* Collided with building, overspeed damage, or some other * prior damage */ crash_cause = 3; } /* Impact tolorance exceeded? */ else if(impact_coeff > 1.0f) { /* Aircraft was in flyable condition but now has contacted * ground with an impact greater than it's tolorance, which * means that it has crashed */ crash_cause = 1; } /* Landed in water and does not have floats? */ else if(over_water && !have_floats) { /* Splash */ crash_cause = 4; } /* Contacted ground at bad angle? */ else { if(dir->pitch > (float)(1.0 * PI)) { if(dir->pitch < (float)(1.75 * PI)) crash_cause = 2; } else { if(dir->pitch > (float)(0.25 * PI)) crash_cause = 2; } if(dir->bank > (float)(1.0 * PI)) { if(dir->bank < (float)(1.75 * PI)) crash_cause = 2; } else { if(dir->bank > (float)(0.25 * PI)) crash_cause = 2; } } #if 0 printf( "Touch down: crash_cause=%i impact_coeff=%.4f\n", crash_cause, impact_coeff ); #endif /* Did the object contact the ground abnormally (did it * "crash")? */ if(crash_cause) { float explosion_radius; sar_position_struct explosion_pos; char text[1024]; /* Set object as crashed in accordance with its type */ /* Aircraft? */ if(obj_aircraft_ptr != NULL) { /* If the crash was a splash then mark the object that * it is on water */ if(over_water) obj_aircraft_ptr->on_water = 1; /* Set all appropriate values for the aircraft to show * that it is crashed */ SARSimSetAircraftCrashed( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, obj_aircraft_ptr ); } else { /* Add support for other types of objects that can crash */ } /* Is the crashed object the player object? */ if(obj_ptr == scene->player_obj_ptr) { /* Mark the player object as crashed on scene */ scene->player_has_crashed = True; /* Check if object has not crashed into anything * prior, such as if the object's airworth state was * not set to SAR_AIR_WORTHY_NOT_FLYABLE or * SAR_AIR_WORTHY_OUT_OF_CONTROL */ if((crash_cause != 3) && (crash_cause != 5)) { /* Set banner message to display the cause of the * crash */ SARBannerMessageAppend(scene, NULL); SARBannerMessageAppend(scene, SAR_MESG_CRASH_BANNER); switch(crash_cause) { case 4: /* Splash */ strcpy(text, SAR_MESG_CRASH_SPLASH); SARBannerMessageAppend(scene, text); break; case 2: /* Landed at bad angle */ strcpy(text, SAR_MESG_CRASH_ROTATION_TOO_STEEP); SARBannerMessageAppend(scene, text); break; case 1: /* Hit ground too hard */ /* There should be exactly one occurance of * "%.0f%%" in * SAR_MESG_CRASH_IMPACTED_PAST_TOLORANCE for * the substitution to work */ sprintf( text, SAR_MESG_CRASH_IMPACTED_PAST_TOLORANCE, (float)(impact_coeff * 100) ); SARBannerMessageAppend(scene, text); break; } /* Set footer to indicate what player should do * now, press space to continue */ SARBannerMessageAppend(scene, SAR_MESG_POST_CRASH_BANNER); } } else { /* An object other than the player object has * crashed */ char numstr[80]; sprintf(numstr, "Object #%i", obj_num); *text = '\0'; strcat(text, "*** "); strncat(text, (obj_ptr->name != NULL) ? obj_ptr->name : numstr, 80 ); strcat(text, " has crashed! ***"); SARMessageAdd(scene, text); } /* Get position and size for the creation of the explosion */ memcpy(&explosion_pos, &obj_ptr->pos, sizeof(sar_position_struct)); explosion_radius = (float)MAX(contact_radius * 1.8, 10.0); /* Begin checking if we should create explosion or splash */ /* Check if object has not crashed into anything * prior, such as if the object's airworth state was * not set to SAR_AIR_WORTHY_NOT_FLYABLE or * SAR_AIR_WORTHY_OUT_OF_CONTROL */ if((crash_cause != 3) && (crash_cause != 5)) { /* Just crashed into ground and did not crash into * anything prior or was not out of control, so we * should create an explosion */ int i, explosion_obj_num = -1; sar_object_struct *explosion_obj_ptr = NULL; sar_external_fueltank_struct *eft_ptr; float fuel_remaining = 10.0f; /* Assume some fuel, in kg */ /* Get amount of fuel remaining on this object */ if(obj_aircraft_ptr != NULL) { fuel_remaining = MAX(obj_aircraft_ptr->fuel, 0.0f); for(i = 0; i < obj_aircraft_ptr->total_external_fueltanks; i++) { eft_ptr = obj_aircraft_ptr->external_fueltank[i]; if((eft_ptr != NULL) ? (eft_ptr->flags & SAR_EXTERNAL_FUELTANK_FLAG_ONBOARD) : False ) fuel_remaining += (eft_ptr->dry_mass + eft_ptr->fuel); } } /* Has fuel and not over water? */ if((fuel_remaining > 0.0f) && !over_water) { /* Create explosion because this object crashed with * fuel */ sar_position_struct smoke_offset; /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create explosion object */ explosion_obj_num = ExplosionCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_EXPLOSION, SAR_STD_TEXNAME_EXPLOSION_IR ); if(explosion_obj_num > -1) { sar_object_explosion_struct *obj_explosion_ptr; explosion_obj_ptr = core_ptr->object[explosion_obj_num]; obj_explosion_ptr = SAR_OBJ_GET_EXPLOSION(explosion_obj_ptr); if(obj_explosion_ptr != NULL) { /* Set lifespan for explosion */ explosion_obj_ptr->life_span = cur_millitime + opt->crash_explosion_life_span; /* Repeat frames until life span is reached */ obj_explosion_ptr->total_frame_repeats = -1; } } /* Create smoke trails object */ smoke_offset.x = 0.0f; smoke_offset.y = 0.0f; smoke_offset.z = explosion_radius; SmokeCreate( scene, &core_ptr->object, &core_ptr->total_objects, SAR_SMOKE_TYPE_SMOKE, &explosion_pos, &smoke_offset, explosion_radius * 1.0f, /* Radius start */ explosion_radius * 3.0f, /* Radius max */ -1.0f, /* Autocalc growth */ 1, /* Hide at max */ 10, /* Total units */ 3000l, /* Respawn interval in ms */ SAR_STD_TEXNAME_SMOKE_DARK, obj_num, cur_millitime + opt->crash_explosion_life_span ); } /* Splash? */ else if(over_water) { /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create splash */ explosion_obj_num = SplashCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_SPLASH, SAR_STD_TEXNAME_SPLASH ); if(explosion_obj_num > -1) { explosion_obj_ptr = core_ptr->object[explosion_obj_num]; /* No need to modify splash values */ } } /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { /* Set spot camera position */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = scene->player_obj_num; } } /* Was out of control? */ else if(crash_cause == 3) { /* Object was out of control and has now just hit the * ground so it needs to crash */ int explosion_obj_num = -1; sar_object_struct *explosion_obj_ptr = NULL; /* We still need to create a splash if landed on water */ if(over_water) { /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create splash (explosion) object */ explosion_obj_num = SplashCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_SPLASH, SAR_STD_TEXNAME_SPLASH ); if(explosion_obj_num > -1) { explosion_obj_ptr = core_ptr->object[explosion_obj_num]; /* No need to modify splash values */ } } /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { /* Set spot camera position */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = scene->player_obj_num; } } /* Play splash or explosion sound */ // only play crash sound the first time if (crash_cause != 5) { if(over_water) { DO_EFFECTS_SPLASH_AIRCRAFT } else { DO_EFFECTS_CRASH_GROUND } } // end of crashed for the first time /* Call mission destroy notify instead of mission land * notify, to let mission know this object has crashed */ SARMissionDestroyNotify(core_ptr, obj_ptr); } else { /* Safe landing (no crash) */ sar_obj_part_struct *lgear_ptr = SARObjGetPartPtr( obj_ptr, SAR_OBJ_PART_TYPE_LANDING_GEAR, 0 ); /* Handle safe landing by object type */ /* Aircraft? */ if(obj_aircraft_ptr != NULL) { /* Mark as on water? */ if(over_water) obj_aircraft_ptr->on_water = 1; else obj_aircraft_ptr->on_water = 0; /* First landing gear down? */ if((lgear_ptr != NULL) ? (lgear_ptr->flags & SAR_OBJ_PART_FLAG_STATE) : False ) { /* Landed with gear down */ /* First landing gear is a ski? */ if((lgear_ptr != NULL) ? (lgear_ptr->flags & SAR_OBJ_PART_FLAG_LGEAR_SKI) : False ) { /* Landing gear is a ski, check if landed * at velocity great enough to cause scrape */ if(obj_aircraft_ptr->speed > SFMMPHToMPC(5)) { DO_EFFECTS_LAND_SKIS_SKID } else { DO_EFFECTS_LAND_SKIS } } else { /* Landing gear is a wheel */ /* landed with brakes on? */ if(obj_aircraft_ptr->wheel_brakes_state > 0) { if(obj_aircraft_ptr->speed > SFMMPHToMPC(10)) { DO_EFFECTS_LAND_WHEEL_SKID } } else { if(obj_aircraft_ptr->speed > SFMMPHToMPC(25)) { DO_EFFECTS_LAND_WHEEL_SKID } } } } else { /* Landed on belly, check if landed at velocity * great enough to cause scrape. */ if(obj_aircraft_ptr->speed > SFMMPHToMPC(5)) { DO_EFFECTS_LAND_BELLY } else { DO_EFFECTS_LAND_SKIS } } } /* Other object type */ else { /* Add support for safe landing of other object types here */ } /* Call mission land notify */ SARMissionLandNotify(core_ptr, obj_ptr, gcc_list, gcc_list_total); } /* Delete list of ground contact objects */ free(gcc_list); gcc_list = NULL; gcc_list_total = 0; #undef DO_EFFECTS_LAND_BELLY #undef DO_EFFECTS_LAND_SKIS #undef DO_EFFECTS_LAND_SKIS_SKID #undef DO_EFFECTS_LAND_WHEEL_SKID #undef DO_EFFECTS_CRASH_GROUND #undef DO_EFFECTS_SPLASH_AIRCRAFT } /* * FDM Overspeed callback. * * Called whenever the FDM is exceeding its maximum expected * speed. * * This function may be called quite often. */ void SARSimOverspeedCB( void *realm_ptr, SFMModelStruct *model, void *client_data, double cur_speed, double overspeed_expected, double overspeed ) { int obj_num; sar_object_struct *obj_ptr; sar_object_aircraft_struct *obj_aircraft_ptr; sar_contact_bounds_struct *cb; sar_scene_struct *scene; SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; scene = core_ptr->scene; if(scene == NULL) return; /* Match object from FDM */ obj_ptr = SARSimMatchObjectFromFDM( core_ptr->object, core_ptr->total_objects, model, &obj_num ); if(obj_ptr == NULL) return; /* Skip overspeed check entirly if in slew mode */ if(SARSimIsSlew(obj_ptr)) return; /* Handle by object type */ 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); if(obj_aircraft_ptr != NULL) { /* Current speed has exceeded actual overspeed? */ if(cur_speed > overspeed) { /* Is aircraft still flyable? */ if(obj_aircraft_ptr->air_worthy_state == SAR_AIR_WORTHY_FLYABLE) { float contact_radius = SARSimGetFlatContactRadius(obj_ptr); /* Set it to be out of control */ obj_aircraft_ptr->air_worthy_state = SAR_AIR_WORTHY_OUT_OF_CONTROL; /* Reduce to 10% hit points (as needed) */ if(obj_ptr->hit_points > (obj_ptr->hit_points_max * 0.10f)) obj_ptr->hit_points = obj_ptr->hit_points_max * 0.10f; /* Get pointer to object's contact bounds structure */ cb = obj_ptr->contact_bounds; if(cb != NULL) { /* Remove SAR_CRASH_FLAG_CRASH_OTHER flag from * object's crash flags so that this object * won't crash into other objects from now on. * * Note that this will not create an explosion when * it hits the ground. */ cb->crash_flags &= ~SAR_CRASH_FLAG_CRASH_OTHER; } /* Delete all effects objects related to this object */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, 0 ); /* Create smoke trails object */ SmokeCreate( scene, &core_ptr->object, &core_ptr->total_objects, SAR_SMOKE_TYPE_SMOKE, &obj_ptr->pos, NULL, contact_radius * 0.25f, /* Radius start */ contact_radius * 2.5f, /* Radius max */ -1.0f, /* Autocalc growth */ 1, /* Hide at max */ 15, /* Total units */ 500, /* Respawn interval in ms */ SAR_STD_TEXNAME_SMOKE_MEDIUM, obj_num, 0 /* Life span */ ); /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { /* Mark player object as has crashed */ scene->player_has_crashed = True; /* Set overspeed crash banner */ SARBannerMessageAppend(scene, NULL); SARBannerMessageAppend(scene, SAR_MESG_CRASH_OVERSPEED_BANNER); #if 0 /* Do not post footer, pilot may still want to land */ SARBannerMessageAppend(scene, SAR_MESG_POST_CRASH_BANNER); */ #endif /* Set spot camera position */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = scene->player_obj_num; } } #if 0 /* Do not call mission destroy notify, pilot may still want to land */ SARMissionDestroyNotify(core_ptr, obj_ptr); #endif } } break; case SAR_OBJ_TYPE_GROUND: 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; } } /* * FDM midair collision callback. This function won't be called * by the SFM library (since all crash detection values passed * to the SFM are False), instead SAR will do collision detection * outside of the SFM level. */ void SARSimCollisionCB( void *realm_ptr, SFMModelStruct *model, SFMModelStruct *obstruction, void *client_data, double impact_coeff ) { /* Ignore this callback, SAR uses its own crash detection * callback functions. */ } /* * Same as SARSimCollisionCB except that it takes inputs in * the form of object pointers, this is for collision detection * on our side (not using the SFM collision check callback). */ void SARSimObjectCollisionCB( void *client_data, /* Core structure */ sar_object_struct *obj_ptr, sar_object_struct *obstruction_obj_ptr, double impact_coeff ) { int n, ref_object = -1; float r, distance_to_camera; float tower_offset_x = 50.0f, tower_offset_y = 50.0f, tower_offset_z = 50.0f; sar_position_struct *pos, *ear_pos, explosion_pos, smoke_offset; sar_direction_struct *dir; sar_scene_struct *scene; sar_object_aircraft_struct *obj_aircraft_ptr; sar_contact_bounds_struct *cb; sar_core_struct *core_ptr = SAR_CORE(client_data); const sar_option_struct *opt; if((core_ptr == NULL) || (obj_ptr == NULL) || (obstruction_obj_ptr == NULL) ) return; opt = &core_ptr->option; scene = core_ptr->scene; if(scene == NULL) return; /* Skip collision check entirly if in slew mode */ if(SARSimIsSlew(obj_ptr)) return; #define DO_PLAY_CRASH_OBSTRUCTION \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ scene->sndsrc, scene->total_sndsrcs, \ "crash_obstruction", \ pos, dir, ear_pos \ ); \ } /* Get pointer to position and direction of victim object */ pos = &obj_ptr->pos; dir = &obj_ptr->dir; /* Get pointer to position of ear */ ear_pos = &scene->ear_pos; /* Calculate distance to camera */ distance_to_camera = (float)SFMHypot3( pos->x - ear_pos->x, pos->y - ear_pos->y, pos->z - ear_pos->z ); /* Check if obstruction object (the `crashed into' object) is * valid. */ if(obstruction_obj_ptr != NULL) { float bearing, bearing_obstruction, bearing_velocity; float theta, theta_absolute, tower_offset; sar_position_struct *pos2, *vel; /* Get pointer to obstruction object's position */ pos2 = &obstruction_obj_ptr->pos; /* Begin setting up victim object's values to mark that it has * crashed into the obstruction object */ /* Change some values on victim object by its type, do not * set object as fully crashed since it's probably * plumitting to the ground. */ 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); if(obj_aircraft_ptr == NULL) break; vel = &obj_aircraft_ptr->vel; /* Calculate bearing of victim object to obstruction * object in world coordinates. */ bearing = (float)SFMSanitizeRadians( (0.5 * PI) - atan2(pos2->y - pos->y, pos2->x - pos->x) ); /* Calculate bearing from world coordinates to * the victim object coordinates. */ bearing_obstruction = (float)SFMSanitizeRadians( bearing - dir->heading ); /* Get direction of velocity relative to victim object */ bearing_velocity = (float)SFMSanitizeRadians( (0.5 * PI) - atan2(vel->y, vel->x) ); /* Calculate angle from bearing_velocity to * bearing_obstruction. */ theta = (float)SFMDeltaRadians( bearing_velocity, bearing_obstruction ); theta_absolute = ((theta < 0.0f) ? -theta : theta); /* If the absolute angle of velocity to direction of * obstruction object is less than (0.5 * PI) then that * means victim object has hit the obstruction object * and that its velocity needs to be changed */ if(theta_absolute < (0.5 * PI)) { double a[3], r[3]; /* r is overloaded */ SFMModelStruct *fdm = obj_aircraft_ptr->fdm; if(fdm != NULL) { #define TAR_PTR fdm a[0] = TAR_PTR->velocity_vector.x; a[1] = TAR_PTR->velocity_vector.y; a[2] = TAR_PTR->velocity_vector.z; MatrixRotateHeading3( a, 2.0 * (theta - (0.5 * PI)), r ); TAR_PTR->velocity_vector.x = r[0] * 0.1; TAR_PTR->velocity_vector.y = r[1] * 0.1; TAR_PTR->velocity_vector.z = r[2] * 0.1; TAR_PTR->speed *= 0.1; #undef TAR_PTR } } /* Begin calculating tower offset */ tower_offset = (float)MAX( SARSimGetFlatContactRadius(obj_ptr) * 4.0, 10.0 ); tower_offset_x = (float)(-sin(bearing) * tower_offset); tower_offset_y = (float)(-cos(bearing) * tower_offset); tower_offset_z = tower_offset; /* Set air worthy state based on if object is already * landed or not */ if(obj_aircraft_ptr->landed) { /* Call SARSimSetAircraftCrashed() procedure since * aircraft is already on ground and won't crash * again */ SARSimSetAircraftCrashed( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, obj_aircraft_ptr ); } else { /* Aircraft is still flying, mark it as out of * control */ obj_aircraft_ptr->air_worthy_state = SAR_AIR_WORTHY_OUT_OF_CONTROL; /* Turn engines off */ obj_aircraft_ptr->engine_state = SAR_ENGINE_OFF; } break; case SAR_OBJ_TYPE_GROUND: 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; } } /* if(obstruction_obj_ptr != NULL) */ /* Get pointer to victim object's contact bounds structure */ cb = obj_ptr->contact_bounds; if(cb != NULL) { /* Remove SAR_CRASH_FLAG_CRASH_OTHER flag from victim * object's crash flags so that the victim object won't * crash into other objects from now on. */ cb->crash_flags &= ~SAR_CRASH_FLAG_CRASH_OTHER; } /* Begin creating explosion */ /* Get position and values for creating explosion object */ memcpy(&explosion_pos, &obj_ptr->pos, sizeof(sar_position_struct)); ref_object = SARGetObjectNumberFromPointer( scene, core_ptr->object, core_ptr->total_objects, obj_ptr ); r = (float)MAX(SARSimGetFlatContactRadius(obj_ptr) * 1.8, 10.0); /* Delete all effects objects related to this object but only * stop smoke trails from respawning. */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, ref_object, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create explosion object */ n = ExplosionCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ r, /* Radius of size in meters */ ref_object, /* Reference object number */ SAR_STD_TEXNAME_EXPLOSION, SAR_STD_TEXNAME_EXPLOSION_IR ); if(n > -1) { sar_object_explosion_struct *obj_explosion_ptr; sar_object_struct *explosion_obj_ptr = core_ptr->object[n]; obj_explosion_ptr = SAR_OBJ_GET_EXPLOSION(explosion_obj_ptr); if(obj_explosion_ptr != NULL) { /* Set lifespan for explosion */ explosion_obj_ptr->life_span = cur_millitime + opt->crash_explosion_life_span; /* Repeat frames until life span is reached */ obj_explosion_ptr->total_frame_repeats = -1; } } /* Create smoke trails object */ smoke_offset.x = 0.0f; smoke_offset.y = 0.0f; smoke_offset.z = r; SmokeCreate( scene, &core_ptr->object, &core_ptr->total_objects, SAR_SMOKE_TYPE_SMOKE, &explosion_pos, &smoke_offset, r * 1.0f, /* Radius start */ r * 3.0f, /* Radius max */ -1.0f, /* Autocalc growth */ 1, /* Hide at max */ 10, /* Total units */ 3000, /* Respawn interval in ms */ SAR_STD_TEXNAME_SMOKE_DARK, ref_object, cur_millitime + opt->crash_explosion_life_span ); /* Play crash obstruction sound */ DO_PLAY_CRASH_OBSTRUCTION /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { char text[128]; /* Mark player object as has crashed */ scene->player_has_crashed = True; /* If camera reference type is not currently tower or spot * then set camera reference type to tower. */ if(((scene->camera_ref == SAR_CAMERA_REF_TOWER) ? (scene->camera_target != scene->player_obj_num) : 1 ) && ((scene->camera_ref == SAR_CAMERA_REF_SPOT) ? (scene->camera_target != scene->player_obj_num) : 1 ) ) { /* Set tower position */ scene->camera_tower_pos.x = obj_ptr->pos.x + tower_offset_x; scene->camera_tower_pos.y = obj_ptr->pos.y + tower_offset_y; scene->camera_tower_pos.z = obj_ptr->pos.z + tower_offset_z; scene->camera_ref = SAR_CAMERA_REF_TOWER; scene->camera_target = scene->player_obj_num; } /* Set scene banner to indicate collision and type */ SARBannerMessageAppend(scene, NULL); SARBannerMessageAppend(scene, SAR_MESG_COLLISION_BANNER); if(obstruction_obj_ptr != NULL) { cb = obstruction_obj_ptr->contact_bounds; *text = '\0'; switch((cb != NULL) ? cb->crash_type : SAR_CRASH_TYPE_OBSTRUCTION) { case SAR_CRASH_TYPE_OBSTRUCTION: strcpy(text, SAR_MESG_CRASH_OBSTRUCTION); break; case SAR_CRASH_TYPE_GROUND: /* Never should occure for midair collisions */ strcpy(text, SAR_MESG_CRASH_GROUND); break; case SAR_CRASH_TYPE_MOUNTAIN: strcpy(text, SAR_MESG_CRASH_MOUNTAIN); break; case SAR_CRASH_TYPE_BUILDING: strcpy(text, SAR_MESG_CRASH_BOULDING); break; case SAR_CRASH_TYPE_AIRCRAFT: strcpy(text, SAR_MESG_CRASH_AIRCRAFT); break; case SAR_CRASH_TYPE_FIRE: strcpy(text, SAR_MESG_CRASH_FIRE); break; } if(*text == '\0') sprintf( text, "UNSUPPORTED COLLISION CODE %i", (int)((cb != NULL) ? cb->crash_type : SAR_CRASH_TYPE_OBSTRUCTION) ); SARBannerMessageAppend(scene, text); } /* Set footer to indicate what pilot should do now */ SARBannerMessageAppend(scene, SAR_MESG_POST_CRASH_BANNER); } #undef DO_PLAY_CRASH_OBSTRUCTION } searchandrescue_1.5.0/sar/image.h0000644000175000017500000000150510104532747015766 0ustar jessejesse/* Image For OpenGL image rendering. */ #ifndef IMAGE_H #define IMAGE_H #include /* * Image Types: */ typedef enum { SAR_IMAGE_TYPE_RGBA, SAR_IMAGE_TYPE_RGB, SAR_IMAGE_TYPE_LUMINANCE } sar_image_type; /* * Image structure: */ typedef struct { sar_image_type type; /* One of SAR_IMAGE_TYPE_* */ int width, height; u_int8_t *data; } sar_image_struct; #define SAR_IMAGE(p) ((sar_image_struct *)(p)) /* In image.c */ extern sar_image_struct *SARImageNew( sar_image_type type, int width, int height, u_int8_t *data ); extern sar_image_struct *SARImageNewFromFile(const char *filename); extern void SARImageDelete(sar_image_struct *img); extern void SARImageDraw( gw_display_struct *display, const sar_image_struct *img, int x, int y, int width, int height ); #endif /* IMAGE_H */ searchandrescue_1.5.0/sar/sarkey.c0000644000175000017500000017005311535552164016206 0ustar jessejesse#include #include #include #include "../include/disk.h" #include "gw.h" #include "sound.h" #include "sarreality.h" #include "messages.h" #include "obj.h" #include "objutils.h" #include "gctl.h" #include "simop.h" #include "simutils.h" #include "textinput.h" #include "cmd.h" #include "sar.h" #include "scenesound.h" #include "sardrawselect.h" #include "sarmenuop.h" #include "sarmenucodes.h" #include "sarsimend.h" #include "sarkey.h" #include "config.h" /* Prototype for all SARKey*() functions */ #define SAR_KEY_FUNC_PROTOTYPE \ sar_core_struct *core_ptr, gw_display_struct *display, \ sar_scene_struct *scene, Boolean state static void SARKeyCameraRefCockpit(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyCameraRefHoist(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyCameraRefMap(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyCameraRefSpot(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyCameraRefTower(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyCommand(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyEscape(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyUnits(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyGraphicsAtmosphere(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyGraphicsTexturedClouds(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyGraphicsTexturedGround(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyGraphicsTexturedObjects(SAR_KEY_FUNC_PROTOTYPE); static void SARKeySoundLevel(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyMusic(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyHelpDisplay(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyPrintScore(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyTimeCompression(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyViewNormalize(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyHoistContact(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyFlightPhysicsDifficulty(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyVisibility(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyAutoPilot(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyLandingGear(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyLights(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyStrobes(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyFLIR(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyTextColor(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyWeatherChange(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyInterceptWayPoint(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyEngine(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyElevatorTrimUp(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyElevatorTrimDown(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyTiltRotors(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyHoistRopeEndSelect(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyDoor(SAR_KEY_FUNC_PROTOTYPE); static int SARKeyRestart(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyRefuelRepair(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyFuel(SAR_KEY_FUNC_PROTOTYPE); static void SARKeySendMessage(SAR_KEY_FUNC_PROTOTYPE); static void SARKeyTimeOfDay(SAR_KEY_FUNC_PROTOTYPE); void SARKey( sar_core_struct *core_ptr, int c, Boolean state, long t ); #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) #define PLAY_SOUND(p) \ { if((opt->event_sounds) && (recorder != NULL)) { \ char *full_path = STRDUP((ISPATHABSOLUTE(p)) ? \ (p) : PrefixPaths(dname.global_data, (p)) \ ); \ SoundStartPlayVoid( \ recorder, full_path, 1.0, 1.0, 0, 0 \ ); \ free(full_path); \ } } /* * Switch camera reference on scene structure to cockpit. */ static void SARKeyCameraRefCockpit(SAR_KEY_FUNC_PROTOTYPE) { int prev_camera_ref; if((scene == NULL) || !state) return; prev_camera_ref = scene->camera_ref; scene->camera_ref = SAR_CAMERA_REF_COCKPIT; scene->camera_target = scene->player_obj_num; if(prev_camera_ref != scene->camera_ref) SARCameraRefTitleSet(scene, "Cockpit"); } /* * Switch camera reference on scene structure to hoist. */ static void SARKeyCameraRefHoist(SAR_KEY_FUNC_PROTOTYPE) { int prev_camera_ref; if((scene == NULL) || !state) return; prev_camera_ref = scene->camera_ref; scene->camera_ref = SAR_CAMERA_REF_HOIST; scene->camera_target = scene->player_obj_num; if(prev_camera_ref != scene->camera_ref) SARCameraRefTitleSet(scene, "Hoist"); } /* * Switch camera reference on scene structure to map. */ static void SARKeyCameraRefMap(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; scene->camera_ref = SAR_CAMERA_REF_MAP; scene->camera_target = -1; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_position_struct *pos_src = &obj_ptr->pos; sar_position_struct *pos_tar = &scene->camera_map_pos; /* Set initial camera position at location of object */ pos_tar->x = pos_src->x; pos_tar->y = pos_src->y; if(pos_tar->z < 1000.0) pos_tar->z = 1000.0; } /* Set mission title as the map camera reference title? */ if(core_ptr->mission != NULL) { sar_mission_struct *mission = core_ptr->mission; if((mission->title != NULL) ? (*mission->title != '\0') : False) SARCameraRefTitleSet(scene, mission->title); } else if((scene->title != NULL) ? (*scene->title != '\0') : False) { SARCameraRefTitleSet(scene, scene->title); } } /* * Switch camera reference on scene structure to spot. * * If the camera reference is already set to spot then the `next' * object will be set as the camera target. */ static void SARKeyCameraRefSpot(SAR_KEY_FUNC_PROTOTYPE) { int obj_num = -1; sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; /* Previous camera reference is spot with set target? */ if((scene->camera_ref == SAR_CAMERA_REF_SPOT) && (scene->camera_target > -1) ) { /* Camera reference was already spot, so cycle camera target * to the `next' object. */ int i, n, type; Boolean seek_backwards = display->shift_key_state; /* Go through objects list twice */ for(n = 0; n < 2; n++) { /* Go through objects list, starting from the * index value as the current value for the camera * target + 1. */ i = scene->camera_target + (seek_backwards ? -1 : 1); while((i >= 0) && (i < core_ptr->total_objects)) { obj_ptr = core_ptr->object[i]; if(obj_ptr == NULL) { seek_backwards ? i-- : i++; continue; } /* Get object type */ type = obj_ptr->type; /* Match following object types */ if((type == SAR_OBJ_TYPE_STATIC) || (type == SAR_OBJ_TYPE_AUTOMOBILE) || (type == SAR_OBJ_TYPE_WATERCRAFT) || (type == SAR_OBJ_TYPE_AIRCRAFT) || /* (type == SAR_OBJ_TYPE_RUNWAY) || (type == SAR_OBJ_TYPE_HELIPAD) || */ (type == SAR_OBJ_TYPE_FUELTANK) || (type == SAR_OBJ_TYPE_HUMAN) || (type == SAR_OBJ_TYPE_PREMODELED) ) break; /* No match, seek next index */ seek_backwards ? i-- : i++; } /* Got matched object? */ if((i >= 0) && (i < core_ptr->total_objects)) { scene->camera_target = obj_num = i; break; } else if(i < 0) { /* Seeked past bottom, warp to top */ scene->camera_target = core_ptr->total_objects; } else if(i >= core_ptr->total_objects) { scene->camera_target = -1; } else { scene->camera_target = -1; } } } else { /* Previous camera reference was not spot, so initially * set to spot and target the player object. */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = obj_num = scene->player_obj_num; } /* At this point obj_num should now be the matched object or -1 * on failed match. */ /* Got matched object? */ obj_ptr = SARObjGetPtr( core_ptr->object, core_ptr->total_objects, obj_num ); if((obj_ptr != NULL) ? (obj_ptr->name != NULL) : 0) { SARCameraRefTitleSet(scene, obj_ptr->name); } else if(obj_num > -1) { char s[80]; sprintf(s, "Object #%i", obj_num); SARCameraRefTitleSet(scene, s); } } /* * Switch camera reference on scene structure to tower. * * The position of the tower will be calculated by a call to * SARSimSetFlyByPosition(). */ static void SARKeyCameraRefTower(SAR_KEY_FUNC_PROTOTYPE) { int prev_camera_ref; if((scene == NULL) || !state) return; prev_camera_ref = scene->camera_ref; scene->camera_ref = SAR_CAMERA_REF_TOWER; scene->camera_target = scene->player_obj_num; SARSimSetFlyByPosition( scene, &core_ptr->object, &core_ptr->total_objects, scene->player_obj_ptr, &scene->camera_tower_pos ); if(prev_camera_ref != scene->camera_ref) SARCameraRefTitleSet(scene, "Tower"); } /* * Maps the command prompt, future key events sent to SARKey() * will then be forwarded to SARTextInputHandleKey() until * the command argument is typed in and processed or aborted. */ static void SARKeyCommand(SAR_KEY_FUNC_PROTOTYPE) { if(!state) return; SARTextInputMap( core_ptr->text_input, "Command", NULL, SARCmdTextInputCB, core_ptr ); } /* * Handles escape key depending on the situation which is checked * in a specific order. The conditions are as follows: * * 1. Check is help screen is displayed, if so then hide it. * * 2. Check if any messages are currently being displayed by the * scene. * * 3. Check if a mission is in progress, and if so map the prompt * for confirmation. * * 4. All else prompt to end simulation. */ static void SARKeyEscape(SAR_KEY_FUNC_PROTOTYPE) { if(!state) return; /* Displaying help? */ if(core_ptr->display_help > 0) { core_ptr->display_help = 0; } /* Scene displaying message? */ else if((scene != NULL) ? (scene->message_display_until > 0) : False) { /* Reset message display until time to 0 and delete * all messages on the scene. This will not change * the size of the message pointer array. */ SARMessageClearAll(scene); } /* Scene displaying camera reference title? */ else if((scene != NULL) ? (scene->camera_ref_title_display_until > 0) : False) { SARCameraRefTitleSet(scene, NULL); } /* Prompt to end mission? */ else if(core_ptr->mission != NULL) { /* Same as end simulation, just prompt text different */ SARTextInputMap( core_ptr->text_input, "Are you sure you want to abort the mission?", NULL, SARTextInputCBQuitSimulation, core_ptr ); } else { SARTextInputMap( core_ptr->text_input, "Are you sure you want to quit simulation?", NULL, SARTextInputCBQuitSimulation, core_ptr ); } } /* * Change units. */ static void SARKeyUnits(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; switch(opt->units) { case SAR_UNITS_ENGLISH: opt->units = SAR_UNITS_METRIC; message = "Units: Metric"; break; case SAR_UNITS_METRIC: opt->units = SAR_UNITS_METRIC_ALT_FEET; message = "Units: Metric (Altitude In Feet)"; break; case SAR_UNITS_METRIC_ALT_FEET: opt->units = SAR_UNITS_ENGLISH; message = "Units: English"; break; } SARMessageAdd(scene, message); } /* * Toggles atmosphere in the global options structure on/off. */ static void SARKeyGraphicsAtmosphere(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* If shift key is held then operation is alternated to be the * celestial toggle. */ if(display->shift_key_state) { if(opt->celestial_objects) { opt->celestial_objects = False; message = "Celestial Objects: Off"; } else { opt->celestial_objects = True; message = "Celestial Objects: On"; } } else { if(opt->atmosphere) { opt->atmosphere = False; message = "Atmosphere: Off"; } else { opt->atmosphere = True; message = "Atmosphere: On"; } } SARMessageAdd(scene, message); } /* * Toggles textured cloud layers in the global options structure * on/off. * * Note that this basically specifies if cloud layers should be * drawn since cloud layers are always textured. If camera is * above highest cloud layer then the highest cloud layer will * always be drawn. */ static void SARKeyGraphicsTexturedClouds(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* If shift key is held then operation is alternated to be the * prop wash toggle. */ if(display->shift_key_state) { if(opt->prop_wash) { opt->prop_wash = False; message = "Prop Wash: Off"; } else { opt->prop_wash = True; message = "Prop Wash: On"; } } else { if(opt->textured_clouds) { opt->textured_clouds = False; message = "Textured Clouds: Off"; } else { opt->textured_clouds = True; message = "Textured Clouds: On"; } } SARMessageAdd(scene, message); } /* * Toggles textured ground in the global options structure on/off. */ static void SARKeyGraphicsTexturedGround(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* If shift key is held then operation is alternated to be the * dual pass depth toggle. */ if(display->shift_key_state) { if(opt->dual_pass_depth) { opt->dual_pass_depth = False; message = "Dual Pass Depth: Off"; } else { opt->dual_pass_depth = True; message = "Dual Pass Depth: On"; } } else { if(opt->textured_ground) { opt->textured_ground = False; message = "Ground Texture: Off"; } else { opt->textured_ground = True; message = "Ground Texture: On"; } } SARMessageAdd(scene, message); } /* * Toggles textured objects in the global options structure on/off. */ static void SARKeyGraphicsTexturedObjects(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* If shift key is held then operation is alternated to be the * smoke trails toggle. */ if(display->shift_key_state) { if(opt->smoke_trails) { opt->smoke_trails = False; message = "Smoke Trails: Off"; } else { opt->smoke_trails = True; message = "Smoke Trails: On"; } } else { if(opt->textured_objects) { opt->textured_objects = False; message = "Object Texture: Off"; } else { opt->textured_objects = True; message = "Object Texture: On"; } } SARMessageAdd(scene, message); } /* * Changes the sound level. */ static void SARKeySoundLevel(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* Was all off? */ if(!opt->engine_sounds && !opt->event_sounds && !opt->voice_sounds ) { opt->event_sounds = True; message = "Sound: Events"; } /* Was events only? */ else if(!opt->engine_sounds && opt->event_sounds && !opt->voice_sounds ) { opt->engine_sounds = True; message = "Sound: Events and Engine"; } /* Was events and engine? */ else if(opt->engine_sounds && opt->event_sounds && !opt->voice_sounds ) { opt->voice_sounds = True; message = "Sound: Events, Engine, and Voice"; } /* All else assume all on */ else { opt->engine_sounds = False; opt->event_sounds = False; opt->voice_sounds = False; message = "Sound: Off"; } SARSceneSoundUpdate( core_ptr, opt->engine_sounds, opt->event_sounds, opt->voice_sounds, opt->music ); SARMessageAdd(scene, message); } /* * Toggles music on/off. */ static void SARKeyMusic(SAR_KEY_FUNC_PROTOTYPE) { const char *message = NULL; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* Was music on? */ if(opt->music) { opt->music = False; message = "Music: Off"; } else { opt->music = True; message = "Music: On"; } SARSceneSoundUpdate( core_ptr, opt->engine_sounds, opt->event_sounds, opt->voice_sounds, opt->music ); SARMessageAdd(scene, message); } /* * Toggles the value display_help on the core structure to display * the next page. * * This specifies if the help screen should be drawn or not and which * page number. */ static void SARKeyHelpDisplay(SAR_KEY_FUNC_PROTOTYPE) { if(!state) return; /* Increment or decrement display_help value to indicate current * page being displayed. * * Remember that help page index starts at 1 not 0. * * If increment exceeds maximum page, then it will be sanitized * in the SARDraw*() functions (not here). */ if(display->shift_key_state) core_ptr->display_help--; else core_ptr->display_help++; if(core_ptr->display_help < 0) core_ptr->display_help = 0; } /* * Prints score, mission status, and passengers on board player * aircraft. */ static void SARKeyPrintScore(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; /* Get player object pointer from scene structure */ obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { if(display->shift_key_state) { /* Debug case, print player position stats to stdout */ sar_direction_struct *dir = &obj_ptr->dir; sar_position_struct *pos = &obj_ptr->pos; /* Print position (for debugging) */ printf( "%i:%2i Player: (hpb) %.0f %.0f %.0f (xyz) %.2f %.2f %.2f(%.2f feet)\n", (int)(scene->tod / 3600), (int)((int)((int)scene->tod / 60) % 60), SFMRadiansToDegrees(dir->heading), SFMRadiansToDegrees(dir->pitch), SFMRadiansToDegrees(dir->bank), pos->x, pos->y, pos->z, SFMMetersToFeet(pos->z) ); } else { /* Print score, mission status, and occupants on * the given player object obj_ptr. If core_ptr->mission * is NULL then only occupants will be printed. */ SARMissionPrintStats( core_ptr, scene, core_ptr->mission, obj_ptr ); } } } /* * Adjusts the time compression. */ static void SARKeyTimeCompression(SAR_KEY_FUNC_PROTOTYPE) { float *tc = &time_compression; if((scene == NULL) || !state) return; /* Restore time compression to 1.0? */ if(display->ctrl_key_state) { *tc = 1.0f; } else { if(display->shift_key_state) { /* Increase time compression */ if(*tc >= 1.0f) { *tc += 1.0f; } else { *tc += 0.25f; if(*tc > 1.0f) *tc = 1.0f; } } else { /* Decrease time compression */ if(*tc > 1.0f) { *tc -= 1.0f; if(*tc < 1.0f) *tc = 1.0f; } else { *tc -= 0.25f; } } } /* Clip time compression */ if(*tc < 0.25f) *tc = 0.25f; else if(*tc > 8.0f) *tc = 8.0f; } /* * Normalizes the zoom and position of the view with respect to * the current camera_ref on the scene. */ static void SARKeyViewNormalize(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; /* Get player object */ /* Handle by camera reference */ switch(scene->camera_ref) { case SAR_CAMERA_REF_HOIST: if(obj_ptr != NULL) { float contact_radius = (float)SARSimGetFlatContactRadius(obj_ptr); sar_direction_struct *dir = &scene->camera_hoist_dir; scene->camera_hoist_dist = (float)MAX(contact_radius, 10.0); dir->heading = (float)(1.0f * PI); dir->pitch = (float)(1.95f * PI); dir->bank = (float)(0.0f * PI); } break; case SAR_CAMERA_REF_MAP: if(obj_ptr != NULL) { sar_position_struct *pos_src = &obj_ptr->pos; sar_position_struct *pos_tar = &scene->camera_map_pos; /* Set camera position at location of object and keep * the camera position at least 1000 meters up */ pos_tar->x = pos_src->x; pos_tar->y = pos_src->y; if(pos_tar->z < 1000.0f) pos_tar->z = 1000.0f; } break; case SAR_CAMERA_REF_TOWER: if(obj_ptr != NULL) { SARSimSetFlyByPosition( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, &scene->camera_tower_pos ); } break; case SAR_CAMERA_REF_SPOT: if(obj_ptr != NULL) { float contact_radius = SARSimGetFlatContactRadius(obj_ptr); sar_direction_struct *dir = &scene->camera_spot_dir; scene->camera_spot_dist = (float)MAX(contact_radius, 10.0); dir->heading = (float)(1.0f * PI); dir->pitch = (float)(1.95f * PI); dir->bank = (float)(0.0f * PI); } break; case SAR_CAMERA_REF_COCKPIT: if(obj_ptr != NULL) { sar_direction_struct *dir = &scene->camera_cockpit_dir; dir->heading = (float)(0.0f * PI); dir->pitch = (float)(0.0f * PI); dir->bank = (float)(0.0f * PI); } break; } } /* * Adjusts hoist contact. */ static void SARKeyHoistContact(SAR_KEY_FUNC_PROTOTYPE) { const char *mesg = SAR_MESG_FLIGHT_PHYSICS_UNSUPPORTED; sar_option_struct *opt = &core_ptr->option; float *hoist_contact = &opt->hoist_contact_expansion_coeff; if((scene == NULL) || !state) return; /* Easy? */ if(*hoist_contact >= 4.0f) { *hoist_contact = 2.0f; mesg = "Hoist Contact: Moderate"; } /* Moderate? */ else if(*hoist_contact >= 2.0f) { *hoist_contact = 1.0f; mesg = "Hoist Contact: Authentic"; } /* All else switch to easy */ else { *hoist_contact = 4.0f; mesg = "Hoist Contact: Easy"; } SARMessageAdd(scene, mesg); } /* * Adjusts flight physics difficulty. */ static void SARKeyFlightPhysicsDifficulty(SAR_KEY_FUNC_PROTOTYPE) { const char *mesg = SAR_MESG_FLIGHT_PHYSICS_UNSUPPORTED; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; switch(opt->flight_physics_level) { case FLIGHT_PHYSICS_EASY: opt->flight_physics_level = FLIGHT_PHYSICS_MODERATE; mesg = SAR_MESG_FLIGHT_PHYSICS_MODERATE; break; case FLIGHT_PHYSICS_MODERATE: opt->flight_physics_level = FLIGHT_PHYSICS_REALISTIC; mesg = SAR_MESG_FLIGHT_PHYSICS_REALISTIC; break; case FLIGHT_PHYSICS_REALISTIC: opt->flight_physics_level = FLIGHT_PHYSICS_EASY; mesg = SAR_MESG_FLIGHT_PHYSICS_EASY; break; } SARMessageAdd(scene, mesg); } /* * Sets maximum visibility. */ static void SARKeyVisibility(SAR_KEY_FUNC_PROTOTYPE) { char text[256]; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; opt->visibility_max += (display->shift_key_state) ? 1 : -1; if(opt->visibility_max > 6) opt->visibility_max = 0; else if(opt->visibility_max < 0) opt->visibility_max = 6; /* The equation to calculate visibility max is: * miles = 3 + (opt->visibility_max * 3) */ switch(opt->units) { case SAR_UNITS_METRIC: case SAR_UNITS_METRIC_ALT_FEET: sprintf( text, "Visibility Max: %.1f km", SFMMilesToMeters(3 + (opt->visibility_max * 3)) / 1000.0f ); break; default: /* SAR_UNITS_ENGLISH */ sprintf( text, "Visibility Max: %i Miles", 3 + (opt->visibility_max * 3) ); break; } SARMessageAdd(scene, text); } /* * Toggle autopilot/autohover or toggle slew mode. */ static void SARKeyAutoPilot(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; /* If ctrl key is held then operation is alternated to be the * slew toggle. */ if(display->ctrl_key_state) { sar_object_aircraft_struct *aircraft; /* Get player object */ obj_ptr = scene->player_obj_ptr; aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); /* Object must be an aircraft in order to toggle slew */ if(aircraft != NULL) { int is_slew = SARSimIsSlew(obj_ptr); if(is_slew) { /* Was in slew mode, now go into previous flight mode */ SARSimSetSlew(obj_ptr, 0); } else { /* Was in some other flight mode, now wanting to enter * enter slew mode. Make sure flight worthyness allows * allows aircraft to go into slew mode */ if(aircraft->air_worthy_state == SAR_AIR_WORTHY_FLYABLE) SARSimSetSlew(obj_ptr, 1); } } } else { sar_object_aircraft_struct *aircraft; /* Get player object */ obj_ptr = scene->player_obj_ptr; aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); /* Object must be an aircraft in order to toggle autopilot */ if(aircraft != NULL) { if(aircraft->autopilot_state == SAR_AUTOPILOT_ON) { aircraft->autopilot_state = SAR_AUTOPILOT_OFF; } else { aircraft->autopilot_state = SAR_AUTOPILOT_ON; aircraft->autopilot_altitude = obj_ptr->pos.z; } } } } /* * Raise/lower landing gears on player object. */ static void SARKeyLandingGear(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; const sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { int state = SARObjLandingGearState(obj_ptr); if(state > -1) SARSimOpLandingGear( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, (state == 0) ? 1 : 0, core_ptr->recorder, opt->event_sounds, SAR_IS_EAR_IN_COCKPIT(scene) ); } } /* * Turns lights (vector lights and spot lights) on/off on the player * object. */ static void SARKeyLights(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; sar_object_aircraft_struct *aircraft; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { if(aircraft->air_worthy_state != SAR_AIR_WORTHY_NOT_FLYABLE) { if(display->ctrl_key_state) { /* Reset spot light direction */ sar_direction_struct *dir = &aircraft->spotlight_dir; dir->heading = (float)SFMDegreesToRadians( SAR_DEF_SPOTLIGHT_HEADING ); dir->pitch = (float)SFMDegreesToRadians( SAR_DEF_SPOTLIGHT_PITCH ); dir->bank = (float)SFMDegreesToRadians( SAR_DEF_SPOTLIGHT_BANK ); } else if(display->shift_key_state) { /* Toggle spot light only */ int state = SARSimGetAttenuateState(obj_ptr); SARSimOpAttenuate(obj_ptr, !state); } else { /* Toggle lighting and spot light */ int state = SARSimGetLightsState(obj_ptr); SARSimOpLights(obj_ptr, !state); SARSimOpAttenuate(obj_ptr, !state); } } } } /* * Turns strobe lights on/off on the player object. */ static void SARKeyStrobes(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; sar_object_aircraft_struct *aircraft; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { if(aircraft->air_worthy_state != SAR_AIR_WORTHY_NOT_FLYABLE) { int state = SARSimGetStrobesState(obj_ptr); SARSimOpStrobes(obj_ptr, !state); } } } /* * Toggles FLIR (night vision) on/off. */ static void SARKeyFLIR(SAR_KEY_FUNC_PROTOTYPE) { snd_recorder_struct *recorder = core_ptr->recorder; const sar_option_struct *opt = &core_ptr->option; if(!state) return; /* Toggle FLIR */ core_ptr->flir = !core_ptr->flir; /* Play sound */ PLAY_SOUND( (core_ptr->flir) ? SAR_DEF_SOUND_FLIR_ON : SAR_DEF_SOUND_FLIR_OFF ); } /* * Brightens or darkens text color on scene. */ static void SARKeyTextColor(SAR_KEY_FUNC_PROTOTYPE) { float g; /* Gamma and base coeff */ sar_color_struct *c; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* Adjust message text color, get just the gamma from the * red compoent (since it should be greyscale). */ c = &opt->message_color; if(display->shift_key_state) g = MAX(c->r - 0.1f, 0.0f); else g = MIN(c->r + 0.1f, 1.0f); /* Set new hud and message text color */ SARSetGlobalTextColorBrightness(core_ptr, g); } /* * Change weather. */ static void SARKeyWeatherChange(SAR_KEY_FUNC_PROTOTYPE) { int i, spin_num; sar_weather_data_struct *weather_data; sar_weather_data_entry_struct *wdp_ptr; sar_menu_struct *m; sar_menu_spin_struct *spin_ptr; sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; /* Get list of weather settings */ weather_data = core_ptr->weather_data; if(weather_data != NULL) { /* Get current weather preset index and increment by 1 */ if(display->shift_key_state) i = opt->last_selected_ffweather - 1; else i = opt->last_selected_ffweather + 1; /* Cycle selection? */ if(i >= weather_data->total_presets) i = 0; if((i >= 0) && (i < weather_data->total_presets)) wdp_ptr = weather_data->preset[i]; else wdp_ptr = NULL; /* Weather data preset structure valid and has a name? */ if((wdp_ptr != NULL) ? (wdp_ptr->name != NULL) : False) { char text[256 + 80]; SARWeatherSetScenePreset( weather_data, scene, wdp_ptr->name ); /* Print new weather preset name */ strcpy(text, "Weather: "); strncat(text, wdp_ptr->name, 256); if((*text) != '\0') SARMessageAdd(scene, text); } /* Rcord new value */ opt->last_selected_ffweather = i; /* Get free flight weather menu */ i = SARMatchMenuByName(core_ptr, SAR_MENU_NAME_FREE_FLIGHT_WEATHER); m = (i > -1) ? core_ptr->menu[i] : NULL; spin_ptr = SAR_MENU_SPIN(SARMenuGetObjectByID( m, SAR_MENU_ID_MENU_FREE_FLIGHT_WEATHER_CONDITION, &spin_num )); /* Restore previously selected item */ spin_ptr->cur_value = opt->last_selected_ffweather; } } /* * Select next intercept way point. */ static void SARKeyInterceptWayPoint(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; /* If ctrl key is pressed then interprite this as a weather * change. */ if(display->ctrl_key_state) { SARKeyWeatherChange(core_ptr, display, scene, state); return; } /* Otherwise change waypoint on player object */ obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { int *cur_intercept = NULL, *total_intercepts = NULL; sar_object_aircraft_struct *aircraft; char text[256]; *text = '\0'; 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: aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { cur_intercept = &aircraft->cur_intercept; total_intercepts = &aircraft->total_intercepts; } break; case SAR_OBJ_TYPE_GROUND: 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; } if((cur_intercept != NULL) && (total_intercepts != NULL)) { /* Change intercept number */ if(display->shift_key_state) *cur_intercept = (*cur_intercept) - 1; else *cur_intercept = (*cur_intercept) + 1; /* Cycle */ if(*cur_intercept >= *total_intercepts) *cur_intercept = 0; else if(*cur_intercept < 0) *cur_intercept = *total_intercepts - 1; if(*cur_intercept < 0) *cur_intercept = 0; if(*total_intercepts > 0) { int i = (*cur_intercept) + 1; sprintf( text, "Selected waypoint %i%s", i, (i == (*total_intercepts)) ? " (last)" : "" ); } else strcpy(text, "No waypoints set"); if((*text) != '\0') SARMessageAdd(scene, text); } } } /* * Turns engine off or initializes engine on the player object. */ static void SARKeyEngine(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; sar_object_aircraft_struct *aircraft; sar_option_struct *opt = &core_ptr->option; static int used_to_be_engine_sound = False; if((scene == NULL) || !state) return; /* Get player object */ obj_ptr = scene->player_obj_ptr; aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if((obj_ptr != NULL) && (aircraft != NULL)) { /* Get current engine state and then change it */ sar_engine_state engine_state = SARSimGetEngineState(obj_ptr); if(((engine_state == SAR_ENGINE_ON) || (engine_state == SAR_ENGINE_INIT)) && display->shift_key_state ) { SARSimOpEngine( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, SAR_ENGINE_OFF, core_ptr->recorder, opt->event_sounds, SAR_IS_EAR_IN_COCKPIT(scene) ); /* turn off engine sound */ if (opt->engine_sounds == True) used_to_be_engine_sound = True; else used_to_be_engine_sound = False; opt->engine_sounds = False; SARSceneSoundUpdate( core_ptr, opt->engine_sounds, opt->event_sounds, opt->voice_sounds, opt->music ); } else if(!display->shift_key_state) { SARSimOpEngine( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, SAR_ENGINE_ON, core_ptr->recorder, opt->event_sounds, SAR_IS_EAR_IN_COCKPIT(scene) ); /* turn on engine sound */ if (used_to_be_engine_sound == True) opt->engine_sounds = True; SARSceneSoundUpdate( core_ptr, opt->engine_sounds, opt->event_sounds, opt->voice_sounds, opt->music ); } } } /* * Increases elevator trim on player object. */ static void SARKeyElevatorTrimUp(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_object_aircraft_struct *aircraft; 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: aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { /* In slew mode, this function moves the aircraft down */ if(aircraft->flight_model_type == SAR_FLIGHT_MODEL_SLEW) { obj_ptr->pos.z -= (float)SFMFeetToMeters( (display->shift_key_state) ? 250.0 : 25.0 ); SARSimWarpObject( scene, obj_ptr, &obj_ptr->pos, &obj_ptr->dir ); } /* All else is regular elevator trim adjusting */ else { if(display->ctrl_key_state) aircraft->elevator_trim = 0.0f; else aircraft->elevator_trim -= (float)( (display->shift_key_state) ? 0.1 : 0.025 ); if(aircraft->elevator_trim < -1.0f) aircraft->elevator_trim = -1.0f; } } break; case SAR_OBJ_TYPE_GROUND: 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; } } } /* * Decreases elevator trim on player object. */ static void SARKeyElevatorTrimDown(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_object_aircraft_struct *aircraft; 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: aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { /* In slew mode, this function moves the aircraft up */ if(aircraft->flight_model_type == SAR_FLIGHT_MODEL_SLEW) { obj_ptr->pos.z += (float)SFMFeetToMeters( (display->shift_key_state) ? 250.0 : 25.0 ); SARSimWarpObject( scene, obj_ptr, &obj_ptr->pos, &obj_ptr->dir ); } /* All else is regular elevator trim adjusting */ else { if(display->ctrl_key_state) aircraft->elevator_trim = 0.0f; else aircraft->elevator_trim += (float)( (display->shift_key_state) ? 0.1 : 0.025 ); if(aircraft->elevator_trim > 1.0f) aircraft->elevator_trim = 1.0f; } } break; case SAR_OBJ_TYPE_GROUND: 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; } } } /* * Tilt rotors/pitch engines. */ static void SARKeyTiltRotors(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_object_aircraft_struct *aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { /* Can rotors pitch? */ if(aircraft->engine_can_pitch == 1) { /* Change flight model */ switch(aircraft->flight_model_type) { case SAR_FLIGHT_MODEL_AIRPLANE: SARSimPitchEngine( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, 0 /* Pitch up */ ); /* SARMessageAdd(scene, "Helicopter Mode"); */ break; /* All else assume helicopter */ default: SARSimPitchEngine( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, 1 /* Pitch forward */ ); /* SARMessageAdd(scene, "Airplane Mode"); */ break; } } } } } /* * Selects different thing (rescue basket or diver) to put at the * end of the player object's rescue hoist rope. */ static void SARKeyHoistRopeEndSelect(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_obj_hoist_struct *hoist = SARObjGetHoistPtr(obj_ptr, 0, NULL); if(hoist != NULL) { sar_hoist_deployment_flags deployments = hoist->deployments, cur_deployment = hoist->cur_deployment; const char *message = NULL; /* Unable to select if hoist's rope is already out */ if(hoist->rope_cur > 0.0f) { message = SAR_MESG_HOIST_END_SELECT_ROPE_OUT; } else { if(cur_deployment == SAR_HOIST_DEPLOYMENT_BASKET) { if(deployments & SAR_HOIST_DEPLOYMENT_DIVER) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_DIVER; else if(deployments & SAR_HOIST_DEPLOYMENT_HOOK) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_HOOK; } else if(cur_deployment == SAR_HOIST_DEPLOYMENT_DIVER) { if(deployments & SAR_HOIST_DEPLOYMENT_HOOK) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_HOOK; else if(deployments & SAR_HOIST_DEPLOYMENT_BASKET) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_BASKET; } else if(cur_deployment == SAR_HOIST_DEPLOYMENT_HOOK) { if(deployments & SAR_HOIST_DEPLOYMENT_BASKET) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_BASKET; else if(deployments & SAR_HOIST_DEPLOYMENT_DIVER) hoist->cur_deployment = SAR_HOIST_DEPLOYMENT_DIVER; } cur_deployment = hoist->cur_deployment; switch(cur_deployment) { case SAR_HOIST_DEPLOYMENT_BASKET: message = SAR_MESG_HOIST_END_SELECT_BASKET; break; case SAR_HOIST_DEPLOYMENT_DIVER: message = SAR_MESG_HOIST_END_SELECT_DIVER; break; case SAR_HOIST_DEPLOYMENT_HOOK: message = SAR_MESG_HOIST_END_SELECT_HOOK; break; } } if(message != NULL) SARMessageAdd(scene, message); } } } /* * Open/close main door on player object. */ static void SARKeyDoor(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_obj_hoist_struct *hoist = SARObjGetHoistPtr(obj_ptr, 0, NULL); sar_obj_part_struct *door_ptr = SARObjGetPartPtr( obj_ptr, SAR_OBJ_PART_TYPE_DOOR_RESCUE, 0 ); if(door_ptr != NULL) { /* Door opened and hoist out? */ if(((hoist == NULL) ? 0 : (hoist->rope_cur > 0.0)) && (door_ptr->flags & SAR_OBJ_PART_FLAG_STATE) ) { /* Door is opened and hoist is out, cannot close * door. */ SARMessageAdd( scene, SAR_MESG_CANNOT_CLOSE_DOOR_BASKET ); } else { /* Check if door was opened? */ if(door_ptr->flags & SAR_OBJ_PART_FLAG_STATE) { /* Since closing door we need to abort any * passengers leaving. */ SARSimOpPassengersSetLeave( scene, obj_ptr, 0, 0 ); } /* This is an explicit door operation, so if opening * the door we need to set the the * SAR_OBJ_PART_FLAG_DOOR_STAY_OPEN flag on it. */ if(door_ptr->flags & SAR_OBJ_PART_FLAG_STATE) { /* Door is already opened, so we're closing * it. When we close the door it will * automatically remove the * SAR_OBJ_PART_FLAG_DOOR_STAY_OPEN. flag. */ } else { /* Door is closed, open it and set the * SAR_OBJ_PART_FLAG_DOOR_STAY_OPEN flag, marking * that the player explicitly opened the door and * it should not automatically start to close on * the next loop. */ door_ptr->flags |= SAR_OBJ_PART_FLAG_DOOR_STAY_OPEN; } /* Set up rescue door values to begin opening or * closing it. */ SARSimOpDoorRescue( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, !(door_ptr->flags & SAR_OBJ_PART_FLAG_STATE) ); } } } } /* * Restart from nearest restarting point or end mission. * * Checks if a mission exists but is no longer in progress * (marked success or failed), in which case will end * simulation. * * If no mission exists then checks if player object is marked * crashed and moves player to nearest restarting point. * * This function returns 1 if the event was handled or 0 if it * was not or error. */ static int SARKeyRestart(SAR_KEY_FUNC_PROTOTYPE) { int obj_num; sar_object_struct *obj_ptr; if((scene == NULL) || !state) return(0); /* Begn restarting simulation by the simulation type */ /* Was there a mission? */ if(core_ptr->mission != NULL) { sar_mission_struct *m = core_ptr->mission; /* Handle by mission state */ switch(m->state) { case MISSION_STATE_IN_PROGRESS: /* Mission still in progress, do nothing */ break; case MISSION_STATE_FAILED: case MISSION_STATE_ACCOMPLISHED: /* End simulation and tabulate mission results */ SARSimEnd(core_ptr); /* Return indicating event was handled */ return(1); break; default: fprintf( stderr, "SARKeyRestart(): Unsupported mission state `%i'\n", m->state ); break; } } /* No mission (assume this is a free flight), check if player * object is marked crashed. */ else if(scene->player_has_crashed) { /* Reset game controller states */ GCtlResetValues(core_ptr->gctl); /* Get references to player objects */ obj_num = scene->player_obj_num; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { /* Move player object to nearest restarting point and * repair it. */ SARSimRestart( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, obj_ptr ); /* Return indicating event was handled */ return(1); } } /* Return indicating no event handled */ return(0); } /* * Refuel and repair aircraft. */ static void SARKeyRefuelRepair(SAR_KEY_FUNC_PROTOTYPE) { sar_object_struct *obj_ptr; if((scene == NULL) || !state) return; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { Boolean obj_ok = False, loc_ok = False, can_refuel = False, can_repair = False, can_dropoff = False; sar_object_aircraft_struct *aircraft; /* Check if object is okay to refuel or repair by its * type */ 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: aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { if(aircraft->landed && (aircraft->air_worthy_state != SAR_AIR_WORTHY_NOT_FLYABLE) ) obj_ok = True; } break; case SAR_OBJ_TYPE_GROUND: 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; } /* Is object okay to be refueled or repaired? */ if(obj_ok) { /* Check if object is at a helipad and get the * facilities (refuel or repair) */ int i, hit_obj_num, list_total, *list; sar_object_struct *hit_obj_ptr; sar_object_helipad_struct *obj_helipad_ptr; /* Get list of objects at the object's location */ list = SARGetGCCHitList( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, scene->player_obj_num, &list_total ); /* Iterate through objects at this object's location * and update the refuel, repair, and dropoff states */ for(i = 0; i < list_total; i++) { hit_obj_num = list[i]; hit_obj_ptr = SARObjGetPtr( core_ptr->object, core_ptr->total_objects, hit_obj_num ); if(hit_obj_ptr == NULL) continue; switch(hit_obj_ptr->type) { case SAR_OBJ_TYPE_GARBAGE: case SAR_OBJ_TYPE_STATIC: case SAR_OBJ_TYPE_AUTOMOBILE: case SAR_OBJ_TYPE_WATERCRAFT: case SAR_OBJ_TYPE_AIRCRAFT: case SAR_OBJ_TYPE_GROUND: case SAR_OBJ_TYPE_RUNWAY: break; case SAR_OBJ_TYPE_HELIPAD: obj_helipad_ptr = SAR_OBJ_GET_HELIPAD(hit_obj_ptr); if(obj_helipad_ptr != NULL) { const sar_helipad_flags flags = obj_helipad_ptr->flags; if(flags & SAR_HELIPAD_FLAG_FUEL) can_refuel = True; if(flags & SAR_HELIPAD_FLAG_REPAIR) can_repair = True; if(flags & SAR_HELIPAD_FLAG_DROPOFF) can_dropoff = True; } loc_ok = True; break; 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; } } free(list); /* Begin refuel and repair of object depending on * available facilities. */ if(loc_ok) { const char *s; if(can_refuel) SARSimOpRefuel(scene, obj_ptr); if(can_repair) SARSimOpRepair(scene, obj_ptr); if(can_refuel && can_repair) s = SAR_MESG_REFUELING_REPAIRS_COMPLETE; else if(can_refuel) s = SAR_MESG_REFUELING_COMPLETE; else if(can_repair) s = SAR_MESG_REPAIRS_COMPLETE; else s = SAR_MESG_NO_FACILITIES; SARMessageAdd(scene, s); /* Can drop off passengers and not playing a mission? */ if(can_dropoff && (core_ptr->mission == NULL)) { int passengers_unloaded = SARSimOpPassengersUnloadAll( scene, obj_ptr ); if(passengers_unloaded > 0) { char s[256]; sprintf(s, "Dropped off %i passengers", passengers_unloaded); SARMessageAdd(scene, s); } } } else { SARMessageAdd( scene, SAR_MESG_NOT_REFUELABLE ); } } else { SARMessageAdd( scene, SAR_MESG_NOT_REFUELABLE ); } } } /* * Prints remaining fuel and statistics, transfers fuel from reserved * tanks, or drop fuel tank. */ static void SARKeyFuel(SAR_KEY_FUNC_PROTOTYPE) { int obj_num; sar_object_struct *obj_ptr; const sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || !state) return; obj_num = scene->player_obj_num; obj_ptr = scene->player_obj_ptr; if(obj_ptr != NULL) { sar_object_aircraft_struct *aircraft; 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: aircraft = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(aircraft != NULL) { if(display->ctrl_key_state) { /* Drop next fuel tank */ SARSimOpDropFuelTankNext( scene, &core_ptr->object, &core_ptr->total_objects, obj_num, obj_ptr ); } else if(display->shift_key_state) { char text[256]; /* Transfer fuel */ float fuel_transfered = SARSimOpTransferFuelFromTanks( scene, obj_ptr ); if(fuel_transfered > 0.0f) { switch(opt->units) { case SAR_UNITS_METRIC: case SAR_UNITS_METRIC_ALT_FEET: sprintf( text, SAR_MESG_RESERVE_FUEL_TRANSFERED, fuel_transfered, "kg" ); break; default: /* SAR_UNITS_ENGLISH */ sprintf( text, SAR_MESG_RESERVE_FUEL_TRANSFERED, SFMKGToLBS(fuel_transfered), "lbs" ); break; } } else { strcpy(text, SAR_MESG_NO_RESERVE_FUEL_TO_TRANSFER); } SARMessageAdd(scene, text); } else { /* Print fuel stats */ int i; sar_external_fueltank_struct *eft_ptr; float throttle_output = SARSimThrottleOutputCoeff( (aircraft->flight_model_type != SAR_FLIGHT_MODEL_SLEW) ? aircraft->flight_model_type : aircraft->last_flight_model_type , aircraft->throttle, aircraft->collective, aircraft->collective_range ); float fuel = aircraft->fuel; /* In kg */ float fuel_rate = aircraft->fuel_rate; /* In kg/cycle */ float aloft_time; /* In seconds */ float external_fuel = 0.0, external_fuel_max = 0.0; char text[256]; /* Add up fuel from external reserved tanks */ for(i = 0; i < aircraft->total_external_fueltanks; i++) { eft_ptr = aircraft->external_fueltank[i]; if(eft_ptr == NULL) continue; if(eft_ptr->flags & SAR_EXTERNAL_FUELTANK_FLAG_ONBOARD) { external_fuel += eft_ptr->fuel; external_fuel_max += eft_ptr->fuel_max; } } /* Calculate time left aloft (include fuel * from external tanks) */ if((fuel_rate * throttle_output) > 0.0f) aloft_time = (float)( ((fuel + external_fuel) / (fuel_rate * throttle_output)) * SAR_CYCLE_TO_SEC_COEFF ); else aloft_time = 0.0f; if(external_fuel_max > 0.0f) { switch(opt->units) { case SAR_UNITS_METRIC: case SAR_UNITS_METRIC_ALT_FEET: sprintf( text, "Int: %.0f(%.0f) kg Ext: %.0f(%.0f) kg Endur: %s", aircraft->fuel, aircraft->fuel_max, external_fuel, external_fuel_max, SARDeltaTimeString( core_ptr, (time_t)aloft_time ) ); break; default: /* SAR_UNITS_ENGLISH */ sprintf( text, "Int: %.0f(%.0f) lbs Ext: %.0f(%.0f) lbs Endur: %s", SFMKGToLBS(aircraft->fuel), SFMKGToLBS(aircraft->fuel_max), SFMKGToLBS(external_fuel), SFMKGToLBS(external_fuel_max), SARDeltaTimeString( core_ptr, (time_t)aloft_time ) ); break; } } else { switch(opt->units) { case SAR_UNITS_METRIC: case SAR_UNITS_METRIC_ALT_FEET: sprintf( text, "Int: %.0f(%.0f) kg Endur: %s", aircraft->fuel, aircraft->fuel_max, SARDeltaTimeString( core_ptr, (time_t)aloft_time ) ); break; default: /* SAR_UNITS_ENGLISH */ sprintf( text, "Int: %.0f(%.0f) lbs Endur: %s", SFMKGToLBS(aircraft->fuel), SFMKGToLBS(aircraft->fuel_max), SARDeltaTimeString( core_ptr, (time_t)aloft_time ) ); break; } } SARMessageAdd(scene, text); } } break; case SAR_OBJ_TYPE_GROUND: 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; } } } /* * Sends a message. */ static void SARKeySendMessage(SAR_KEY_FUNC_PROTOTYPE) { if(!state) return; /* Map prompt for entering a message to send */ SARTextInputMap( core_ptr->text_input, "Message", NULL, SARTextInputCBSendMessage, core_ptr ); } /* * Adjusts the time of day on the scene structure. */ static void SARKeyTimeOfDay(SAR_KEY_FUNC_PROTOTYPE) { const char *time_str; char text[256]; if((scene == NULL) || !state) return; /* Increase or decrease time of day */ if(display->shift_key_state) scene->tod -= (float)(0.25 * 3600.0); else scene->tod += (float)(0.25 * 3600.0); time_str = (const char *)SARTimeOfDayString(core_ptr, scene->tod); sprintf( text, "%s %s", SAR_MESG_TIME_OF_DAY, time_str ); SARMessageAdd(scene, text); } /* * SAR keyboard event handler. Front end for handling all in game * keyboard events. * * If the in game text input prompt is mapped then the key event * will be forwarded to the prompt input handler. * * If key event key code c does not match any key operation to be * handled then the keyboard event will be forwarde to * GCtlHandleKey(). */ void SARKey( sar_core_struct *core_ptr, int c, Boolean state, long t ) { gw_display_struct *display = core_ptr->display; sar_scene_struct *scene = core_ptr->scene; /* Inputs for all SARKey*() functions */ #define SAR_KEY_FUNC_INPUT core_ptr, display, scene, state /* Turns off autorepeat when key is pressed and turns autorepeat * back on when key is released. */ #define DO_HAS_NO_AUTOREPEAT { \ GWKeyboardAutoRepeat(display, (Boolean)!state); \ } /* Initial simulation key checks come first */ /* Space bar initially `continues' if mission failed or * ended, or moves player to nearest restarting point on * free flights. */ if(c == ' ') { /* Space bar always implicitly clears scene's sticky banner * message. */ SARBannerMessageAppend(scene, NULL); /* Do `restart' procedure, conditions will be checked by * the function. Returns positive if event was handled. */ if(SARKeyRestart(SAR_KEY_FUNC_INPUT) > 0) { /* Event was handled, return immediatly. The simulation * may have ended or other memory greatly changed. */ return; } } /* Handle key as a regular simulation action */ switch(c) { /* Debug value adjustment */ case 'x': case 'X': if((scene != NULL) && (display != NULL) && state) { debug_value += (float)((display->shift_key_state) ? 0.25 : -0.25); fprintf(stderr, "Debug value set to %.2f\n", debug_value); } break; case 's': case 'S': /* Print score */ DO_HAS_NO_AUTOREPEAT if(display->ctrl_key_state) SARKeySoundLevel(SAR_KEY_FUNC_INPUT); else SARKeyPrintScore(SAR_KEY_FUNC_INPUT); break; case GWKeyBackSpace: /* Re-center/normalize view */ DO_HAS_NO_AUTOREPEAT SARKeyViewNormalize(SAR_KEY_FUNC_INPUT); break; case GWKeyF1: /* Help display toggle */ DO_HAS_NO_AUTOREPEAT SARKeyHelpDisplay(SAR_KEY_FUNC_INPUT); break; case GWKeyF2: /* Switch camera ref to cockpit */ DO_HAS_NO_AUTOREPEAT SARKeyCameraRefCockpit(SAR_KEY_FUNC_INPUT); break; case GWKeyF3: /* Switch camera ref to spot */ DO_HAS_NO_AUTOREPEAT SARKeyCameraRefSpot(SAR_KEY_FUNC_INPUT); break; case GWKeyF4: /* Switch camera ref to tower */ DO_HAS_NO_AUTOREPEAT SARKeyCameraRefTower(SAR_KEY_FUNC_INPUT); break; case GWKeyF5: /* Switch camera ref to hoist's rescue basket */ DO_HAS_NO_AUTOREPEAT SARKeyCameraRefHoist(SAR_KEY_FUNC_INPUT); break; case 'm': case 'M': /* Switch camera ref to map */ DO_HAS_NO_AUTOREPEAT if(display->ctrl_key_state) SARKeyMusic(SAR_KEY_FUNC_INPUT); else SARKeyCameraRefMap(SAR_KEY_FUNC_INPUT); break; case 'u': if(display->ctrl_key_state) SARKeyUnits(SAR_KEY_FUNC_INPUT); break; case GWKeyF9: /* Toggle textured ground or dual pass depth */ DO_HAS_NO_AUTOREPEAT SARKeyGraphicsTexturedGround(SAR_KEY_FUNC_INPUT); break; case GWKeyF10: /* Toggle atmosphere */ DO_HAS_NO_AUTOREPEAT SARKeyGraphicsAtmosphere(SAR_KEY_FUNC_INPUT); break; case GWKeyF11: /* Toggle textured objects */ DO_HAS_NO_AUTOREPEAT SARKeyGraphicsTexturedObjects(SAR_KEY_FUNC_INPUT); break; case GWKeyF12: /* Toggle textured clouds or prop wash */ DO_HAS_NO_AUTOREPEAT SARKeyGraphicsTexturedClouds(SAR_KEY_FUNC_INPUT); break; case 0x1b: /* Escape */ DO_HAS_NO_AUTOREPEAT SARKeyEscape(SAR_KEY_FUNC_INPUT); break; case '/': /* Command prompt map */ DO_HAS_NO_AUTOREPEAT SARKeyCommand(SAR_KEY_FUNC_INPUT); break; case 'z': case 'Z': /* Adjust time compression */ DO_HAS_NO_AUTOREPEAT SARKeyTimeCompression(SAR_KEY_FUNC_INPUT); break; case 'a': case 'A': /* Slew toggle */ /* This will later include autopilot/autohover */ DO_HAS_NO_AUTOREPEAT SARKeyAutoPilot(SAR_KEY_FUNC_INPUT); break; /* Raise/lower landing gears on player object */ case 'g': case 'G': DO_HAS_NO_AUTOREPEAT SARKeyLandingGear(SAR_KEY_FUNC_INPUT); break; /* Turn lights on/off on player object */ case 'l': case 'L': DO_HAS_NO_AUTOREPEAT SARKeyLights(SAR_KEY_FUNC_INPUT); break; /* Turn strobe lights on/off on player object */ case 'o': case 'O': DO_HAS_NO_AUTOREPEAT SARKeyStrobes(SAR_KEY_FUNC_INPUT); break; /* Toggle FLIR (night vision) on/off */ case 'i': case 'I': DO_HAS_NO_AUTOREPEAT SARKeyFLIR(SAR_KEY_FUNC_INPUT); break; case 'h': case 'H': if(display->ctrl_key_state) { /* Adjust hoist contact expansion coefficient */ DO_HAS_NO_AUTOREPEAT SARKeyHoistContact(SAR_KEY_FUNC_INPUT); } else { /* Adjust text color */ SARKeyTextColor(SAR_KEY_FUNC_INPUT); } break; /* Select next intercept way point */ case 'w': case 'W': DO_HAS_NO_AUTOREPEAT SARKeyInterceptWayPoint(SAR_KEY_FUNC_INPUT); break; /* Engine off/init */ case 'e': case 'E': DO_HAS_NO_AUTOREPEAT SARKeyEngine(SAR_KEY_FUNC_INPUT); break; /* Elevator trim down */ case GWKeyHome: SARKeyElevatorTrimDown(SAR_KEY_FUNC_INPUT); break; /* Elevator trim */ case GWKeyEnd: SARKeyElevatorTrimUp(SAR_KEY_FUNC_INPUT); break; /* Send message */ case '\'': DO_HAS_NO_AUTOREPEAT SARKeySendMessage(SAR_KEY_FUNC_INPUT); break; /* Adjust time of day */ case 't': case 'T': SARKeyTimeOfDay(SAR_KEY_FUNC_INPUT); break; /* Select rescue hoist rope end deployment type */ case 'p': case 'P': DO_HAS_NO_AUTOREPEAT SARKeyHoistRopeEndSelect(SAR_KEY_FUNC_INPUT); break; case 'd': case 'D': if(display->ctrl_key_state) { /* Adjust flight physics dificulty */ DO_HAS_NO_AUTOREPEAT SARKeyFlightPhysicsDifficulty(SAR_KEY_FUNC_INPUT); } else { /* Open/close rescue door */ DO_HAS_NO_AUTOREPEAT SARKeyDoor(SAR_KEY_FUNC_INPUT); } break; case 'v': case 'V': SARKeyVisibility(SAR_KEY_FUNC_INPUT); break; case 'c': case 'C': DO_HAS_NO_AUTOREPEAT break; case 'y': case 'Y': /* Tilt rotors/pitch engine */ DO_HAS_NO_AUTOREPEAT SARKeyTiltRotors(SAR_KEY_FUNC_INPUT); break; case 'r': case 'R': DO_HAS_NO_AUTOREPEAT SARKeyRefuelRepair(SAR_KEY_FUNC_INPUT); break; case 'f': case 'F': DO_HAS_NO_AUTOREPEAT SARKeyFuel(SAR_KEY_FUNC_INPUT); break; default: /* Some other key, let the game controller handle it */ GCtlHandleKey( display, core_ptr->gctl, c, state, display->alt_key_state, display->ctrl_key_state, display->shift_key_state, t, lapsed_millitime ); break; } /* Calling function will redraw whenever a key event is recieved GWPostRedraw((gw_display_struct *)ptr); */ #undef SAR_KEY_FUNC_INPUT } #undef SAR_KEY_FUNC_PROTOTYPE searchandrescue_1.5.0/sar/v3dgl.h0000644000175000017500000001134210104532752015717 0ustar jessejesse/* V3D OpenGL Front End Handles V3D to OpenGL IOs/Conversions/Calling/etc Depends on v3dhf.c and v3dtex.c */ #ifndef V3DGL_H #define V3DGL_H #include "v3dhf.h" #include "v3dmh.h" #include "v3dmodel.h" #include "v3dmp.h" #include "v3dtex.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef FALSE # define FALSE 0 #endif #ifndef TRUE # define TRUE 1 #endif /* * gl interpritation structure, contains a legend on how to convert * V3D data to gl data. */ typedef struct { #define V3D_GLFLAG_COORDINATE_AXIS (1 << 0) #define V3D_GLFLAG_TEXTURE_KEEP (1 << 1) #define V3D_GLFLAG_ALLOW_TRANSLATIONS (1 << 2) #define V3D_GLFLAG_ALLOW_ROTATIONS (1 << 3) #define V3D_GLFLAG_FLIP_WINDING (1 << 4) #define V3D_GLFLAG_PASS_NORMALS (1 << 5) #define V3D_GLFLAG_UNITLIZE_NORMALS (1 << 6) #define V3D_GLFLAG_PASS_TEXCOORDS (1 << 7) #define V3D_GLFLAG_TEXTURE_NAME_CASE_SENSITIVE (1 << 8) #define V3D_GLFLAG_MATERIAL_PROPERTIES (1 << 9) #define V3D_GLFLAG_FACES (1 << 10) #define V3D_GLFLAG_ENABLE_BLENDING (1 << 11) #define V3D_GLFLAG_SET_BLEND_FUNC (1 << 12) #define V3D_GLFLAG_HEIGHTFIELD_BASE_DIR (1 << 13) #define V3D_GLFLAG_TEXTURE_BASE_DIR (1 << 14) /* Determines which members are set in this structure, any * of V3D_GLFLAG_*. */ unsigned int flags; #define V3D_GLCOORDINATE_AXIS_SCIENTIFIC 0 /* x, y, z. */ #define V3D_GLCOORDINATE_AXIS_GL 1 /* x, z, -y. */ int coordinate_axis; #define V3D_GLTEXTURE_KEEP_ALWAYS 0 /* Keep all textures. */ #define V3D_GLTEXTURE_KEEP_ASNEEDED 1 /* Keep if specified and used. */ int texture_keep; int allow_translations; /* Ignore translate primitives if FALSE. */ int allow_rotations; /* Ignore rotate primitives if FALSE. */ int flip_winding; /* Flip winding if TRUE. */ #define V3D_GLPASS_NORMALS_AS_NEEDED 0 #define V3D_GLPASS_NORMALS_ALWAYS 1 #define V3D_GLPASS_NORMALS_NEVER 2 int pass_normals; int unitlize_normals; /* Convert normals to unit length before * passing to GL. */ #define V3D_GLPASS_TEXCOORDS_AS_NEEDED 0 /* Only when a texture is bounded. */ #define V3D_GLPASS_TEXCOORDS_ALWAYS 1 #define V3D_GLPASS_TEXCOORDS_NEVER 2 int pass_texcoords; int texture_name_case_sensitive; /* TRUE for case sensitive texture * name matching. */ #define V3D_GLPASS_MATERIAL_PROPERTIES_NEVER 0 #define V3D_GLPASS_MATERIAL_PROPERTIES_INSTEAD_COLOR 1 #define V3D_GLPASS_MATERIAL_PROPERTIES_WITH_COLOR 2 int material_properties; /* Material properties from color * primitives will be set if this * is TRUE. */ #define V3D_GLFACES_FRONT 0 /* Account for only the front face. */ #define V3D_GLFACES_BACK 1 /* Account for only the back face. */ #define V3D_GLFACES_FRONT_AND_BACK 2 /* Account for both sides. */ int faces; #define V3D_GLENABLE_BLENDING_NEVER 0 #define V3D_GLENABLE_BLENDING_AS_NEEDED 1 /* Enables/disables GL_BLEND as needed. */ int enable_blending; int set_blend_func; /* need to work on this. */ char *heightfield_base_dir; /* Directory prefix for relative heightfields. */ char *texture_base_dir; /* Directory prefix for relative textures. */ /* More members may be added in the future. */ } v3d_glinterprite_struct; /* * gl resources structure, this structure keeps track of all the * loaded gl resources. Such as the loaded textures and gl * interpritation legend. * * This resource needs to be kept around by the calling function * and passed to gl loading routines untill all gl operations for * the V3D models data that it came from are no longer in use * and no longer needed. */ typedef struct { /* V3D to GL interpritation specifications. */ v3d_glinterprite_struct *glinterprite; /* List of loaded textures. */ v3d_texture_ref_struct **texture; int total_textures; } v3d_glresource_struct; extern v3d_glinterprite_struct *V3DGLInterpriteNew(void); extern void V3DGLInterpriteDelete(v3d_glinterprite_struct *glinterp); extern v3d_glresource_struct *V3DGLResourceNew(void); extern v3d_glresource_struct *V3DGLResourceNewFromModelData( const v3d_glinterprite_struct *glinterp, void **mh_item, int total_mh_items, v3d_model_struct **model, int total_models ); extern int V3DGLResourceSetInterpritation( v3d_glresource_struct *glres, const v3d_glinterprite_struct *glinterp ); extern v3d_glinterprite_struct *V3DGLResourceGetInterpritation( v3d_glresource_struct *glres ); extern void V3DGLResourceDelete(v3d_glresource_struct *glres); /* V3D model to GL interpritation processing. */ extern void V3DGLProcessModelExtra( v3d_glresource_struct *glres, v3d_model_struct *m, void *client_data, void (*extra_cb)(v3d_model_struct *, const char *, void *) ); extern void V3DGLProcessModel( v3d_glresource_struct *glres, v3d_model_struct *m ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* V3DGL_H */ searchandrescue_1.5.0/sar/sardrawpm_ptt.c0000644000175000017500000001320210104532750017555 0ustar jessejesse#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 SARDrawPremodeledPowerTransmissionTower(SAR_DRAW_PREMODELED_PROTOTYPE); /* * Draws a premodeled power transmission tower. */ void SARDrawPremodeledPowerTransmissionTower(SAR_DRAW_PREMODELED_PROTOTYPE) { gw_display_struct *display = dc->display; state_gl_struct *state = &display->state_gl; GLenum shade_model_mode = state->shade_model_mode; int i; float sx, sy, sz; /* Scale */ /* All hard coded coordinates will produce an object of unit * size (height = 1.0) * * So the sx, sy, and sz scale coefficients will simply multiply * each point */ /* Calculate scales, all based on height */ sx = sy = sz = obj_premodeled_ptr->height; /* Set up gl states */ StateGLShadeModel(state, GL_FLAT); glColor4f(0.45f, 0.45f, 0.45f, 1.0f); /* Draw close range model? */ if(camera_dist < 2000.0f) { /* Draw two passes (one for the north side, the other for * the south side. */ for(i = 0; i < 2; i++) { glBegin(GL_LINE_STRIP); { /* Base */ glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(-0.12f * sx, 0.0f * sz, -(0.12f * sy)); glVertex3f(-0.08f * sx, 0.2f * sz, -(0.08f * sy)); glVertex3f(0.08f * sx, 0.2f * sz, -(0.08f * sy)); glVertex3f(0.12f * sx, 0.0f * sz, -(0.12f * sy)); glVertex3f(-0.08f * sx, 0.2f * sz, -(0.08f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.12f * sx, 0.0f * sz, -(0.12f * sy)); glVertex3f(0.08f * sx, 0.2f * sz, -(0.08f * sy)); glVertex3f(-0.05f * sx, 0.4f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.4f * sz, -(0.05f * sy)); glVertex3f(-0.08f * sx, 0.2f * sz, -(0.08f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.08f * sx, 0.2f * sz, -(0.08f * sy)); glVertex3f(-0.05f * sx, 0.4f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.4f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.05f * sx, 0.4f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.4f * sz, -(0.05f * sy)); glVertex3f(0.08f * sx, 0.2f * sz, -(0.08f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.9f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.0f * sx, 1.0f * sz, -(0.0f * sy)); glVertex3f(-0.05f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.9f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(-0.25f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(-0.27f * sx, 0.56f * sz, -(0.0f * sy)); glVertex3f(-0.22f * sx, 0.62f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.59f * sz, -(0.05f * sy)); glVertex3f(-0.25f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(-0.22f * sx, 0.62f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.65f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(0.05f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.25f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.27f * sx, 0.56f * sz, -(0.0f * sy)); glVertex3f(0.22f * sx, 0.62f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.59f * sz, -(0.05f * sy)); glVertex3f(0.25f * sx, 0.65f * sz, -(0.05f * sy)); glVertex3f(0.22f * sx, 0.62f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.65f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(-0.05f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(-0.23f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(-0.25f * sx, 0.81f * sz, -(0.0f * sy)); glVertex3f(-0.2f * sx, 0.87f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.84f * sz, -(0.05f * sy)); glVertex3f(-0.23f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(-0.2f * sx, 0.87f * sz, -(0.05f * sy)); glVertex3f(-0.05f * sx, 0.9f * sz, -(0.05f * sy)); } glEnd(); glBegin(GL_LINE_STRIP); { glVertex3f(0.05f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.23f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.25f * sx, 0.81f * sz, -(0.0f * sy)); glVertex3f(0.2f * sx, 0.87f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.84f * sz, -(0.05f * sy)); glVertex3f(0.23f * sx, 0.9f * sz, -(0.05f * sy)); glVertex3f(0.2f * sx, 0.87f * sz, -(0.05f * sy)); glVertex3f(0.05f * sx, 0.9f * sz, -(0.05f * sy)); } glEnd(); /* Flip the y scale value to draw the south side */ sy *= -1.0f; } } else { /* Draw far model */ glBegin(GL_LINES); { glNormal3f(0.0f, 1.0f, 0.0f); glVertex3f(0.0f * sx, 0.0f * sz, -(0.0f * sy)); glVertex3f(0.0f * sx, 1.0f * sz, -(0.0f * sy)); glVertex3f( 0.27f * sx, 0.62f * sz, -(0.0f * sy)); glVertex3f(-0.27f * sx, 0.62f * sz, -(0.0f * sy)); glVertex3f( 0.26f * sx, 0.9f * sz, -(0.0f * sy)); glVertex3f(-0.26f * sx, 0.9f * sz, -(0.0f * sy)); } glEnd(); } /* Reget y scale, since it has been modified in the above loop */ sy = obj_premodeled_ptr->height; /* Restore gl states */ StateGLShadeModel(state, shade_model_mode); } searchandrescue_1.5.0/sar/human.c0000644000175000017500000001511710104532747016013 0ustar jessejesse#include #include #include #include "../include/string.h" #include "sfm.h" #include "obj.h" #include "objutils.h" #include "sarreality.h" #include "human.h" #include "config.h" sar_human_data_entry_struct *SARHumanMatchEntryByName( sar_human_data_struct *hd, const char *name ); sar_human_data_struct *SARHumanPresetsInit(void *core_ptr); void SARHumanPresetsShutdown(sar_human_data_struct *hd); void SARHumanEntryDelete( sar_human_data_struct *hd, sar_human_data_entry_struct *entry ); int SARHumanCreate( sar_human_data_struct *hd, sar_scene_struct *scene, sar_object_struct ***object, int *total_objects, sar_obj_flags_t human_flags, const char *name ); void SARHumanSetObjectPreset( sar_human_data_struct *hd, sar_object_struct *obj_ptr, const char *name ); #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) ? strlen(s) : 0) #define STRISEMPTY(s) (((s) != NULL) ? (*(s) == '\0') : 1) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) /* * Returns a pointer to the entry structure on the given hd that * matches name. * * Can return NULL on failed match or error. */ sar_human_data_entry_struct *SARHumanMatchEntryByName( sar_human_data_struct *hd, const char *name ) { int i; sar_human_data_entry_struct *entry; if((hd == NULL) || STRISEMPTY(name)) return(NULL); for(i = 0; i < hd->total_presets; i++) { entry = hd->preset[i]; if(entry == NULL) continue; if(entry->name != NULL) { if(!strcasecmp(entry->name, name)) return(entry); } } return(NULL); } /* * Initializes a new sar_human_data_struct structure and returns * the pointer to it. * * This pointer must be freed by the calling function by a call to * SARHumanPresetsShutdown(). */ sar_human_data_struct *SARHumanPresetsInit(void *core_ptr) { sar_human_data_struct *hd = (sar_human_data_struct *)calloc( 1, sizeof(sar_human_data_struct) ); if(hd == NULL) return(hd); hd->core_ptr = core_ptr; return(hd); } /* * Deallocates all human preset resources on the given * sar_human_data_struct structure and the structure itself. * * The given pointer must not be referenced again after calling * this function. */ void SARHumanPresetsShutdown(sar_human_data_struct *hd) { int i; if(hd == NULL) return; /* Deallocate each preset human entry structure */ for(i = 0; i < hd->total_presets; i++) SARHumanEntryDelete( hd, hd->preset[i] ); free(hd->preset); hd->preset = NULL; hd->total_presets = 0; free(hd); } /* * Deallocates the given human entry structure and all its * resources. */ void SARHumanEntryDelete( sar_human_data_struct *hd, sar_human_data_entry_struct *entry ) { if(entry == NULL) return; free(entry->name); free(entry); } /* * Creates a new object of type SAR_OBJ_TYPE_HUMAN in the given * scene. * * Returns the index to the newly added object or -1 on failure. * * If name is not NULL, then the human object will be modeled after * the one matching name on the given human presets data structure. */ int SARHumanCreate( sar_human_data_struct *hd, sar_scene_struct *scene, sar_object_struct ***object, int *total_objects, sar_obj_flags_t human_flags, const char *name ) { int obj_num; sar_object_struct *obj_ptr; sar_object_human_struct *human; if((scene == NULL) || (object == NULL) || (total_objects == NULL)) return(-1); /* Create new human object */ obj_num = SARObjNew( scene, object, total_objects, SAR_OBJ_TYPE_HUMAN ); obj_ptr = ((obj_num < 0) ? NULL : (*object)[obj_num]); if(obj_ptr == NULL) return(-1); /* Get pointer to human data substructure */ human = SAR_OBJ_GET_HUMAN(obj_ptr); if(human == NULL) return(obj_num); /* Visual range */ obj_ptr->range = SAR_HUMAN_DEF_RANGE; /* Set contact bounds, this is needed so we can pick up human * and do other size detection with it. */ SARObjAddContactBoundsCylendrical( obj_ptr, 0, 0, /* Crash flags, crash type */ (float)SAR_HUMAN_CONTACT_RADIUS, (float)SAR_HUMAN_CONTACT_ZMIN, (float)SAR_HUMAN_CONTACT_ZMAX ); /* Temperature */ obj_ptr->temperature = 1.0f; /* Set human flags */ human->flags = human_flags; /* Set default animation rate */ human->anim_rate = SAR_HUMAN_ANIM_RATE; /* Water ripples texture */ human->water_ripple_tex_num = SARGetTextureRefNumberByName( scene, SAR_STD_TEXNAME_WATER_RIPPLE ); /* Reset other human object values here */ human->intercepting_object = -1; human->intercepting_object_distance2d = human->intercepting_object_distance3d = 0.0; /* Number of assisting humans */ human->assisting_humans = 0; /* Model human object values to preset values from the human * data presets. */ SARHumanSetObjectPreset( hd, obj_ptr, name ); return(obj_num); } /* * Sets the specified object (which must be of type * SAR_OBJ_TYPE_HUMAN) to the human presets data entry given by * name on the given hd. * * If obj_ptr is invalid, not of type SAR_OBJ_TYPE_HUMAN, or the * given name of a human data entry could not be found on the hd * then no operation will be performed. */ void SARHumanSetObjectPreset( sar_human_data_struct *hd, sar_object_struct *obj_ptr, const char *name ) { sar_object_human_struct *human; sar_human_data_entry_struct *entry; if((hd == NULL) || (obj_ptr == NULL) || (name == NULL)) return; /* Match human presets data entry by the given name */ entry = SARHumanMatchEntryByName(hd, name); if(entry == NULL) return; human = SAR_OBJ_GET_HUMAN(obj_ptr); if(human == NULL) return; /* Begin setting values from the entry to the human object */ /* Color palette */ memcpy( &human->color[0], &entry->color[0], SAR_HUMAN_COLORS_MAX * sizeof(sar_color_struct) ); /* Height in meters */ human->height = entry->height; /* Weight in kg */ human->mass = entry->mass; /* Number of assisting humans */ human->assisting_humans = entry->assisting_humans; /* Color palette for assisting humans */ memcpy( &human->assisting_human_color[0], &entry->assisting_human_color[0], SAR_HUMAN_COLORS_MAX * sizeof(sar_color_struct) ); /* Add support for other things that need to be coppied here */ } searchandrescue_1.5.0/sar/sardrawpm_controltower.c0000644000175000017500000001461310104532750021516 0ustar jessejesse#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 "sardrawpm.h" #include "sardrawdefs.h" void SARDrawPremodeledControlTower(SAR_DRAW_PREMODELED_PROTOTYPE); /* * Draws a premodeled control tower. */ void SARDrawPremodeledControlTower(SAR_DRAW_PREMODELED_PROTOTYPE) { gw_display_struct *display = dc->display; state_gl_struct *state = &display->state_gl; sar_scene_struct *scene = dc->scene; StateGLBoolean lighting = state->lighting; GLenum shade_model_mode = state->shade_model_mode; float x_min, x_max, y_min, y_max, z_max, z_roof; int i, tex_num; /* Calculate bounds */ x_max = obj_premodeled_ptr->length / 2.0f; x_min = -x_max; y_max = obj_premodeled_ptr->width / 2.0f; y_min = -y_max; z_max = (float)MAX( obj_premodeled_ptr->height - 4.0, 1.0 ); z_roof = obj_premodeled_ptr->height; /* Set up gl states */ StateGLShadeModel(state, GL_FLAT); /* Walls */ if(dc->flir) { StateGLDisable(state, GL_LIGHTING); V3DTextureSelect(NULL); SARDrawSetColorFLIRTemperature(obj_ptr->temperature); } else { i = 0; if(i < SAR_OBJ_PREMODEL_MAX_TEXTURES) tex_num = obj_premodeled_ptr->tex_num[i]; else tex_num = -1; if(SARIsTextureAllocated(scene, tex_num)) V3DTextureSelect(scene->texture_ref[tex_num]); else V3DTextureSelect(NULL); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } glBegin(GL_QUADS); { /* North wall */ glNormal3f(0.0f, 0.0f, -1.0f); glTexCoord2f(1, 1 - 0); glVertex3f(x_min, 0, -y_max); glTexCoord2f(1, 1 - 1); glVertex3f(x_min, z_max, -y_max); glTexCoord2f(0, 1 - 1); glVertex3f(x_max, z_max, -y_max); glTexCoord2f(0, 1 - 0); glVertex3f(x_max, 0, -y_max); /* West wall */ glNormal3f(-1.0f, 0.0f, 0.0f); glTexCoord2f(0, 1 - 0); glVertex3f(x_min, 0, -y_min); glTexCoord2f(0, 1 - 1); glVertex3f(x_min, z_max, -y_min); glTexCoord2f(1, 1 - 1); glVertex3f(x_min, z_max, -y_max); glTexCoord2f(1, 1 - 0); glVertex3f(x_min, 0, -y_max); /* South wall */ glNormal3f(0.0f, 0.0f, 1.0f); glTexCoord2f(0, 1 - 0); glVertex3f(x_max, 0, -y_min); glTexCoord2f(0, 1 - 1); glVertex3f(x_max, z_max, -y_min); glTexCoord2f(1, 1 - 1); glVertex3f(x_min, z_max, -y_min); glTexCoord2f(1, 1 - 0); glVertex3f(x_min, 0, -y_min); /* East wall */ glNormal3f(1.0f, 0.0f, 0.0f); glTexCoord2f(0, 1 - 0); glVertex3f(x_max, 0, -y_max); glTexCoord2f(0, 1 - 1); glVertex3f(x_max, z_max, -y_max); glTexCoord2f(1, 1 - 1); glVertex3f(x_max, z_max, -y_min); glTexCoord2f(1, 1 - 0); glVertex3f(x_max, 0, -y_min); } glEnd(); /* Control tower windows */ if(dc->flir) { } else if(scene->tod_code != SAR_TOD_CODE_DAY) { StateGLDisable(state, GL_LIGHTING); V3DTextureSelect(NULL); glColor4f(0.25f, 0.20f, 0.05f, 1.0f); } else { V3DTextureSelect(NULL); glColor4f(0.05f, 0.05f, 0.0f, 1.0f); } glBegin(GL_QUADS); { /* North */ glNormal3f(0.0f, -0.2f, -0.8f); glVertex3f(x_max, z_max, -y_max); glVertex3f(x_min, z_max, -y_max); glVertex3f(x_min, z_roof, (-y_max * 1.1f)); glVertex3f(x_max, z_roof, (-y_max * 1.1f)); glNormal3f(0.6f, -0.2f, -0.6f); glVertex3f(x_max, z_max, -y_max); glVertex3f(x_max, z_max, -y_max); glVertex3f(x_max, z_roof, (-y_max * 1.1f)); glVertex3f((x_max * 1.1f), z_roof, -y_max); /* East */ glNormal3f(0.8f, -0.2f, 0.0f); glVertex3f(x_max * 1.1f, z_roof, -y_max); glVertex3f(x_max * 1.1f, z_roof, -y_min); glVertex3f(x_max, z_max, -y_min); glVertex3f(x_max, z_max, -y_max); glNormal3f(0.6f, -0.2f, 0.6f); glVertex3f(x_max, z_max, -y_min); glVertex3f(x_max, z_max, -y_min); glVertex3f(x_max * 1.1f, z_roof, -y_min); glVertex3f(x_max, z_roof, -y_min * 1.1f); /* South */ glNormal3f(0.0f, -0.2f, 0.8f); glVertex3f(x_min, z_max, -y_min); glVertex3f(x_max, z_max, -y_min); glVertex3f(x_max, z_roof, -y_min * 1.1f); glVertex3f(x_min, z_roof, -y_min * 1.1f); glNormal3f(-0.6f, -0.2f, 0.6f); glVertex3f(x_min, z_max, -y_min); glVertex3f(x_min, z_max, -y_min); glVertex3f(x_min, z_roof, -y_min * 1.1f); glVertex3f(x_min * 1.1f, z_roof, -y_min); /* West */ glNormal3f(-0.8f, -0.2f, 0.0f); glVertex3f(x_min, z_max, -y_max); glVertex3f(x_min, z_max, -y_min); glVertex3f(x_min * 1.1f, z_roof, -y_min); glVertex3f(x_min * 1.1f, z_roof, -y_max); glNormal3f(-0.6f, -0.2f, -0.6f); glVertex3f(x_min, z_max, -y_max); glVertex3f(x_min, z_max, -y_max); glVertex3f(x_min * 1.1f, z_roof, -y_max); glVertex3f(x_min, z_roof, -y_max * 1.1f); } glEnd(); /* Roof */ if(!dc->flir) { if(lighting) StateGLEnable(state, GL_LIGHTING); /* Select roof texture */ i = 1; if(i < SAR_OBJ_PREMODEL_MAX_TEXTURES) tex_num = obj_premodeled_ptr->tex_num[i]; else tex_num = -1; if(SARIsTextureAllocated(scene, tex_num)) V3DTextureSelect(scene->texture_ref[tex_num]); else V3DTextureSelect(NULL); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } glBegin(GL_QUADS); { /* Roof */ glNormal3f(0.0f, 1.0f, 0.0f); glTexCoord2f(1, 1 - 0); glVertex3f(x_max * 1.1f, z_roof, -y_max); glTexCoord2f(1, 1 - 1); glVertex3f(x_max, z_roof, -y_max * 1.1f); glTexCoord2f(0, 1 - 1); glVertex3f(x_min, z_roof, -y_max * 1.1f); glTexCoord2f(0, 1 - 0); glVertex3f(x_min * 1.1f, z_roof, -y_max); glTexCoord2f(0, 1 - 0); glVertex3f(x_min * 1.1f, z_roof, -y_min); glTexCoord2f(0, 1 - 1); glVertex3f(x_min, z_roof, -y_min * 1.1f); glTexCoord2f(1, 1 - 1); glVertex3f(x_max, z_roof, -y_min * 1.1f); glTexCoord2f(1, 1 - 0); glVertex3f(x_max * 1.1f, z_roof, -y_min); glTexCoord2f(1, 1 - 0); glVertex3f(x_min * 1.1f, z_roof, -y_min); glTexCoord2f(1, 1 - 1); glVertex3f(x_max * 1.1f, z_roof, -y_min); glTexCoord2f(0, 1 - 1); glVertex3f(x_max * 1.1f, z_roof, -y_max); glTexCoord2f(0, 1 - 0); glVertex3f(x_min * 1.1f, z_roof, -y_max); } glEnd(); /* Restore gl states */ StateGLShadeModel(state, shade_model_mode); if(lighting) StateGLEnable(state, GL_LIGHTING); } searchandrescue_1.5.0/sar/this_platform.ini0000644000175000017500000000003511344252666020112 0ustar jessejesseLinux 2.6.31-14-generic i686 searchandrescue_1.5.0/sar/sarsimend.c0000644000175000017500000001400410104532751016655 0ustar jessejesse#include #include #include #include #ifdef __MSW__ # include #else # include # include #endif #include "gw.h" #include "messages.h" #include "obj.h" #include "mission.h" #include "sar.h" #include "missionio.h" #include "sceneio.h" #include "sarmenuop.h" #include "sarmenucodes.h" #include "sarsimend.h" #include "config.h" static void SARSimEndMissionTabulate( sar_core_struct *core_ptr, sar_mission_struct *mission ); void SARSimEnd(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) /* * Updates the mission log map menu with the information from the * current mission (but does switch to the log map menu. */ static void SARSimEndMissionTabulate( sar_core_struct *core_ptr, sar_mission_struct *mission ) { char *s; const char *name; sar_player_stat_struct *pstat; sar_menu_struct *m; sar_scene_struct *scene = core_ptr->scene; int player_obj_num; sar_object_struct *player_obj_ptr; if(scene == NULL) return; /* Get player object */ player_obj_num = scene->player_obj_num; player_obj_ptr = scene->player_obj_ptr; pstat = SARPlayerStatCurrent(core_ptr, NULL); if(pstat != NULL) name = pstat->name; else name = (player_obj_ptr != NULL) ? player_obj_ptr->name : NULL; /* Enough information to begin tabulating mission? */ if(True) { /* Update player stats and get mission ending statement */ switch(mission->state) { case MISSION_STATE_IN_PROGRESS: /* Mission was still in progress, aborted */ if(pstat != NULL) pstat->missions_failed++; /* Counts as failed */ s = STRDUP("*** MISSION ABORTED ***"); break; case MISSION_STATE_FAILED: /* Mission failed */ if(pstat != NULL) pstat->missions_failed++; s = STRDUP("*** MISSION FAILED ***"); break; case MISSION_STATE_ACCOMPLISHED: /* Mission accomplished */ if(pstat != NULL) { pstat->missions_succeeded++; pstat->score += SAR_POINTS_MISSION_ACCOMPLISHED; } s = STRDUP("*** MISSION ACCOMPLISHED ***"); break; default: fprintf( stderr, "SARSimEndMissionTabulate(): Unsupported mission progress state code `%i'\n", mission->state ); s = STRDUP("Error tabulating mission results!"); break; } } /* Log final mission event */ if(s != NULL) { SARMissionLogEvent( core_ptr, mission, /* SAR_MISSION_LOG_EVENT_COMMENT, */ SAR_MISSION_LOG_EVENT_LAND, -1.0, (player_obj_ptr != NULL) ? &player_obj_ptr->pos : NULL, NULL, 0, s, fname.mission_log ); free(s); s = NULL; } /* Update player stats on the players list menu */ m = SARMatchMenuByNamePtr(core_ptr, SAR_MENU_NAME_PLAYER); if(m != NULL) { int list_num; sar_menu_list_struct *list = SAR_MENU_LIST(SARMenuGetObjectByID( m, SAR_MENU_ID_PLAYER_LIST, &list_num )); if(list != NULL) { int i = list->selected_item; list->selected_item = -1; SARMenuListSelect( core_ptr->display, m, list_num, i, True, /* Scroll to */ False /* Redraw */ ); } } /* Get mission log map menu */ m = SARMatchMenuByNamePtr(core_ptr, SAR_MENU_NAME_MISSION_LOG_MAP); /* Load map and markings from the given mission log file to the * given map object */ SARMissionLoadMissionLogToMenuMap( core_ptr, m, fname.mission_log ); } /* * Procedure to end simulation, this function should be called as the * procedure to tabulate the end of a mission or simulation and * return to the menus. * * The simulation type (campaign, mission, freeflight, etc) will * be checked. */ void SARSimEnd(sar_core_struct *core_ptr) { gw_display_struct *display; const char *switch_to_menu_name = NULL; const sar_option_struct *opt; if(core_ptr == NULL) return; display = core_ptr->display; opt = &core_ptr->option; if(opt->runtime_debug) printf("SARSimEnd(): Ending simulation...\n"); /* Check if a mission structure is defined which implies the * simulation involved a mission (and possibly a campaign) */ if(core_ptr->mission != NULL) { /* Mission structure is allocated, implying that there is * a mission going on */ sar_mission_struct *mission = core_ptr->mission; if(opt->runtime_debug) printf("SARSimEnd(): Tabulating mission results...\n"); /* Tabulate mission results */ SARSimEndMissionTabulate(core_ptr, mission); /* Set mission menu as the menu to switch back to after * the simulation. */ switch_to_menu_name = SAR_MENU_NAME_MISSION_LOG_MAP; /* Destroy the mission structure, it is no longer needed */ SARMissionDelete(mission); core_ptr->mission = mission = NULL; } else { /* No mission structure available, implying this was probably * a free flight */ /* Set free flight menu as the menu to switch back to after * the simulation */ switch_to_menu_name = SAR_MENU_NAME_FREE_FLIGHT; } /* Delete scene */ SARSceneDestroy( core_ptr, core_ptr->scene, &core_ptr->object, &core_ptr->total_objects ); free(core_ptr->scene); core_ptr->scene = NULL; if(opt->runtime_debug) printf("SARSimEnd(): Switching back to menus...\n"); /* Show pointer cursor */ GWShowCursor(display); /* Switch to 2D, select main menu (and thus redrawing it) */ SARMenuGLStateReset(display); /* If no menu name to switch to then assume main menu */ if(switch_to_menu_name == NULL) switch_to_menu_name = SAR_MENU_NAME_MAIN; SARMenuSwitchToMenu(core_ptr, switch_to_menu_name); /* Restore keyboard auto repeat, this may be needed since a key * may have been pressed to end a mission and while its held down * the mission may end and auto repeat is not reset since the * key release of the key in question is not handled when back in * menus */ GWKeyboardAutoRepeat(display, True); if(opt->runtime_debug) printf("SARSimEnd(): Done.\n"); } searchandrescue_1.5.0/sar/simcontact.c0000644000175000017500000004251511545432654017057 0ustar jessejesse#include #include #include #include "sarreality.h" #include "obj.h" #include "objutils.h" #include "simcb.h" #include "simutils.h" #include "simcontact.h" int SARSimCrashContactCheck( sar_core_struct *core_ptr, sar_object_struct *obj_ptr ); int SARSimHoistDeploymentContactCheck( sar_core_struct *core_ptr, sar_object_struct *obj_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))) /* * Checks if object obj_ptr has come in contact with another object * on the given core structure. * * Returns the object number of the object that has come in * contact with or -1 if there was no contact. * * Proper procedure will be performed if the object has crashed. */ int SARSimCrashContactCheck( sar_core_struct *core_ptr, sar_object_struct *obj_ptr ) { int i; float dr, z, d; float z1_min, z1_max, z2_min, z2_max; sar_object_struct *obj_ptr2; const sar_contact_bounds_struct *cb_src = obj_ptr->contact_bounds, *cb_tar; const sar_position_struct *pos_src = &obj_ptr->pos, *pos_tar; /* If there is no contact bounds on the source object then * there is no need to do contact check */ if(cb_src == NULL) return(-1); /* Handle by source contact shape */ switch(cb_src->contact_shape) { case SAR_CONTACT_SHAPE_SPHERICAL: /* Iterate through objects */ for(i = 0; i < core_ptr->total_objects; i++) { obj_ptr2 = core_ptr->object[i]; if(obj_ptr2 == NULL) continue; cb_tar = obj_ptr2->contact_bounds; if(cb_tar == NULL) continue; /* Target not crashable? */ if(!(cb_tar->crash_flags & SAR_CRASH_FLAG_CRASH_CAUSE)) continue; /* Skip ourself */ if(obj_ptr2 == obj_ptr) continue; pos_tar = &obj_ptr2->pos; /* Handle by target object contact shape */ switch(cb_tar->contact_shape) { /* Spherical to Spherical */ case SAR_CONTACT_SHAPE_SPHERICAL: /* Check 2d distance for contact first */ dr = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); if((dr - cb_src->contact_radius - cb_tar->contact_radius) > 0.0f ) break; /* Calculate spherical radius and then check if * in contact */ z = pos_tar->z - pos_src->z; d = (float)SFMHypot2(dr, z); if((d - cb_src->contact_radius - cb_tar->contact_radius) <= 0.0f ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1f ); return(i); } break; /* Spherical to Cylendrical */ case SAR_CONTACT_SHAPE_CYLENDRICAL: /* Check 2d distance for contact first */ dr = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); if((dr - cb_src->contact_radius - cb_tar->contact_radius) > 0.0f ) break; /* Sloppy check on vertical height */ z = pos_tar->z; if((pos_src->z >= (z + cb_tar->contact_h_min)) && (pos_src->z <= (z + cb_tar->contact_h_max)) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1 ); return(i); } break; /* Spherical to Rectangular */ case SAR_CONTACT_SHAPE_RECTANGULAR: /* We'll be treating the source object as a square * object based on its contact radius. */ /* First check z bounds. */ z1_min = pos_src->z - cb_src->contact_radius; z1_max = pos_src->z + cb_src->contact_radius; z2_min = pos_tar->z + cb_tar->contact_z_min; z2_max = pos_tar->z + cb_tar->contact_z_max; if((z1_min <= z2_max) && (z2_min <= z1_max) ) { /* Calculate relative deltas from target object * to source object. */ float dx = pos_src->x - pos_tar->x, dy = pos_src->y - pos_tar->y, src_radius = cb_src->contact_radius; float dx2, dy2, x_min, x_max, y_min, y_max; /* Rotate dx and dy about the center of the target * object inversly incase target object has * a rotated heading. */ dx2 = (cb_tar->cos_heading * dx) + (cb_tar->sin_heading * dy); dy2 = (cb_tar->cos_heading * dy) - (cb_tar->sin_heading * dx); /* Calculate x and y bounds, add source object's * contact bounds to increase the bounds. */ x_min = cb_tar->contact_x_min - src_radius; x_max = cb_tar->contact_x_max + src_radius; y_min = cb_tar->contact_y_min - src_radius; y_max = cb_tar->contact_y_max + src_radius; /* Check if rotated dx2 and dy2 are in bounds. */ if((dx2 >= x_min) && (dx2 <= x_max) && (dy2 >= y_min) && (dy2 <= y_max) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1f ); return(i); } } break; } } break; case SAR_CONTACT_SHAPE_CYLENDRICAL: /* Iterate through objects */ for(i = 0; i < core_ptr->total_objects; i++) { obj_ptr2 = core_ptr->object[i]; if(obj_ptr2 == NULL) continue; cb_tar = obj_ptr2->contact_bounds; if(cb_tar == NULL) continue; /* Target not crashable? */ if(!(cb_tar->crash_flags & SAR_CRASH_FLAG_CRASH_CAUSE)) continue; /* Skip ourself */ if(obj_ptr2 == obj_ptr) continue; pos_tar = &obj_ptr2->pos; /* Handle by target object contact shape */ switch(cb_tar->contact_shape) { /* Cylendrical to Spherical */ case SAR_CONTACT_SHAPE_SPHERICAL: /* Check 2d distance for contact first */ dr = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); if((dr - cb_src->contact_radius - cb_tar->contact_radius) > 0.0f ) break; /* Sloppy check on vertical height */ z = pos_tar->z; /* if((z >= (pos_src->z + cb_src->contact_h_min)) && (z <= (pos_src->z + cb_src->contact_h_max)) Adding contact radius check */ if ( (z + cb_tar->contact_radius >= (pos_src->z + cb_src->contact_h_min)) && (z - cb_tar->contact_radius <= (pos_src->z + cb_src->contact_h_max) ) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1f ); return(i); } break; /* Cylendrical to Cylendrical */ case SAR_CONTACT_SHAPE_CYLENDRICAL: /* Check 2d distance for contact first */ dr = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); if((dr - cb_src->contact_radius - cb_tar->contact_radius) > 0.0f ) break; /* Get height bounds */ z1_min = pos_src->z + cb_src->contact_h_min; z1_max = pos_src->z + cb_src->contact_h_max; z2_min = pos_tar->z + cb_tar->contact_h_min; z2_max = pos_tar->z + cb_tar->contact_h_max; /* Check height bounds */ if((z1_min <= z2_max) && (z2_min <= z1_max) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1 ); return(i); } break; /* Cylendrical to Rectangular */ case SAR_CONTACT_SHAPE_RECTANGULAR: /* First check z bounds */ z1_min = pos_src->z + cb_src->contact_h_min; z1_max = pos_src->z + cb_src->contact_h_max; z2_min = pos_tar->z + cb_tar->contact_z_min; z2_max = pos_tar->z + cb_tar->contact_z_max; if((z1_min <= z2_max) && (z2_min <= z1_max) ) { /* Calculate relative deltas from target object * to source object */ float dx = pos_src->x - pos_tar->x, dy = pos_src->y - pos_tar->y, src_radius = cb_src->contact_radius; float dx2, dy2, x_min, x_max, y_min, y_max; /* Rotate dx and dy about the center of the target * object inversly incase target object has * a rotated heading */ dx2 = (cb_tar->cos_heading * dx) + (cb_tar->sin_heading * dy); dy2 = (cb_tar->cos_heading * dy) - (cb_tar->sin_heading * dx); /* Check if rotated dx and dy are in bounds * with the target object contact bounds. * Increase the bounds by the cylendrical * radius of the source object. */ x_min = cb_tar->contact_x_min - src_radius; x_max = cb_tar->contact_x_max + src_radius; y_min = cb_tar->contact_y_min - src_radius; y_max = cb_tar->contact_y_max + src_radius; if((dx2 >= x_min) && (dx2 <= x_max) && (dy2 >= y_min) && (dy2 <= y_max) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1 ); return(i); } } break; } } break; case SAR_CONTACT_SHAPE_RECTANGULAR: /* Iterate through objects */ for(i = 0; i < core_ptr->total_objects; i++) { obj_ptr2 = core_ptr->object[i]; if(obj_ptr2 == NULL) continue; cb_tar = obj_ptr2->contact_bounds; if(cb_tar == NULL) continue; /* Target not crashable? */ if(!(cb_tar->crash_flags & SAR_CRASH_FLAG_CRASH_CAUSE)) continue; /* Skip ourself */ if(obj_ptr2 == obj_ptr) continue; pos_tar = &obj_ptr2->pos; /* Handle by target object contact shape */ switch(cb_tar->contact_shape) { /* Rectangular to Spherical */ case SAR_CONTACT_SHAPE_SPHERICAL: /* We'll be treating the source object as a square * object based on its contact radius. */ /* First check z bounds. */ z1_min = pos_src->z + cb_src->contact_z_min; z1_max = pos_src->z + cb_src->contact_z_max; z2_min = pos_tar->z - cb_tar->contact_radius; z2_max = pos_tar->z + cb_tar->contact_radius; if((z1_min <= z2_max) && (z2_min <= z1_max) ) { /* Calculate relative deltas from source object * to target object */ float dx = pos_tar->x - pos_src->x, dy = pos_tar->y - pos_src->y, tar_radius = cb_tar->contact_radius; float dx2, dy2, x_min, x_max, y_min, y_max; /* Rotate dx and dy about the center of the source * object inversly if source object has a rotated * heading */ dx2 = (cb_src->cos_heading * dx) + (cb_src->sin_heading * dy); dy2 = (cb_src->cos_heading * dy) - (cb_src->sin_heading * dx); /* Calculate x and y bounds, add target object's * contact bounds to increase the bounds. */ x_min = cb_src->contact_x_min - tar_radius; x_max = cb_src->contact_x_max + tar_radius; y_min = cb_src->contact_y_min - tar_radius; y_max = cb_src->contact_y_max + tar_radius; /* Check if rotated dx2 and dy2 are in bounds. */ if((dx2 >= x_min) && (dx2 <= x_max) && (dy2 >= y_min) && (dy2 <= y_max) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1f ); return(i); } } break; /* Rectangular to Cylendrical */ case SAR_CONTACT_SHAPE_CYLENDRICAL: /* First check z bounds */ z1_min = pos_src->z + cb_src->contact_z_min; z1_max = pos_src->z + cb_src->contact_z_max; z2_min = pos_tar->z + cb_tar->contact_h_min; z2_max = pos_tar->z + cb_tar->contact_h_max; if((z1_min <= z2_max) && (z2_min <= z1_max) ) { /* Calculate relative deltas from source object * to target object */ float dx = pos_tar->x - pos_src->x, dy = pos_tar->y - pos_src->y, tar_radius = cb_tar->contact_radius; float dx2, dy2, x_min, x_max, y_min, y_max; /* Rotate dx and dy about the center of the source * object inversly if target object has a rotated * heading */ dx2 = (cb_src->cos_heading * dx) + (cb_src->sin_heading * dy); dy2 = (cb_src->cos_heading * dy) - (cb_src->sin_heading * dx); /* Check if rotated dx and dy are in bounds * with the target object contact bounds. * Increase the bounds by the cylendrical * radius of the source object. */ x_min = cb_src->contact_x_min - tar_radius; x_max = cb_src->contact_x_max + tar_radius; y_min = cb_src->contact_y_min - tar_radius; y_max = cb_src->contact_y_max + tar_radius; if((dx2 >= x_min) && (dx2 <= x_max) && (dy2 >= y_min) && (dy2 <= y_max) ) { SARSimObjectCollisionCB( core_ptr, obj_ptr, obj_ptr2, 1.1 ); return(i); } } break; /* Rectangular to Rectangular */ case SAR_CONTACT_SHAPE_RECTANGULAR: /* TODO */ break; } } break; } return(-1); } /* * Hoist deployment contact check. * * Checks if an object that can be picked up is within range of the * hoist's deployment to be picked up by the hoist's deployment. * * If an object has come in contact then the proper procedure will * be taken. * * Inputs assumed valid. * * Returns the object number of the picked up object or -1 on no * match. */ int SARSimHoistDeploymentContactCheck( sar_core_struct *core_ptr, sar_object_struct *obj_ptr ) { Boolean need_break; int tar_obj_num, matched_obj_num = -1; float d, contact_radius; sar_object_struct *tar_obj_ptr; sar_object_human_struct *human_ptr; sar_obj_hoist_struct *hoist; const sar_position_struct *pos_src, *pos_tar; const sar_contact_bounds_struct *cb_tar; sar_scene_struct *scene = core_ptr->scene; const sar_option_struct *opt = &core_ptr->option; /* Get first hoist on object, if the object does not have a * hoist then that there is nothing to check */ hoist = SARObjGetHoistPtr(obj_ptr, 0, NULL); if(hoist == NULL) return(matched_obj_num); /* Hoist fully retracted? */ if(hoist->rope_cur <= 0.0f) return(matched_obj_num); /* Get hoist deployment's flat contact radius * * If this is the player object then multiply the contact radius * with the hoist contact expansion coefficient */ contact_radius = hoist->contact_radius * 2.0f * ((scene->player_obj_ptr == obj_ptr) ? MAX(opt->hoist_contact_expansion_coeff, 1.0f) : 1.0f); pos_src = &hoist->pos; /* Hoist deployment's position */ /* Iterate through objects, looking for one that can be picked * up by the hoist's deployment */ for(tar_obj_num = 0; tar_obj_num < core_ptr->total_objects; tar_obj_num++) { tar_obj_ptr = core_ptr->object[tar_obj_num]; if(tar_obj_ptr == NULL) continue; /* Get contact bounds for target object */ cb_tar = tar_obj_ptr->contact_bounds; if(cb_tar == NULL) continue; #if 0 /* It is safe to bypass this check */ /* Contact shapes for target object must be cylendrical or * spherical shaped */ if((cb_tar->contact_shape != SAR_CONTACT_SHAPE_SPHERICAL) && (cb_tar->contact_shape != SAR_CONTACT_SHAPE_CYLENDRICAL) ) continue; #endif /* Handle by target object type */ switch(tar_obj_ptr->type) { case SAR_OBJ_TYPE_GARBAGE: case SAR_OBJ_TYPE_STATIC: case SAR_OBJ_TYPE_AUTOMOBILE: case SAR_OBJ_TYPE_WATERCRAFT: case SAR_OBJ_TYPE_AIRCRAFT: case SAR_OBJ_TYPE_GROUND: case SAR_OBJ_TYPE_RUNWAY: case SAR_OBJ_TYPE_HELIPAD: break; case SAR_OBJ_TYPE_HUMAN: human_ptr = SAR_OBJ_GET_HUMAN(tar_obj_ptr); if(human_ptr == NULL) break; /* Does not want to be picked up? */ if(!(human_ptr->flags & SAR_HUMAN_FLAG_NEED_RESCUE)) break; pos_tar = &tar_obj_ptr->pos; /* Check contact bounds by target object's contact * shape * * Reset need_break to False, it will be to True if * there was NO contact */ need_break = False; switch(cb_tar->contact_shape) { case SAR_CONTACT_SHAPE_SPHERICAL: /* Calculate distance */ d = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); /* Within rescue basket pickup distance? */ if((d - contact_radius - cb_tar->contact_radius) > 0.0f ) { need_break = True; break; } /* Is target object under the rescue basket? */ if((pos_tar->z + cb_tar->contact_radius) < (pos_src->z + hoist->contact_z_min) ) { need_break = True; break; } break; case SAR_CONTACT_SHAPE_CYLENDRICAL: /* Calculate distance */ d = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); /* Within rescue basket pickup distance? */ if((d - contact_radius - cb_tar->contact_radius) > 0.0f ) { need_break = True; break; } /* Is target object under the rescue basket? */ if((pos_tar->z + cb_tar->contact_h_max) < (pos_src->z + hoist->contact_z_min) ) { need_break = True; break; } break; case SAR_CONTACT_SHAPE_RECTANGULAR: /* Calculate distance */ d = (float)SFMHypot2( pos_tar->x - pos_src->x, pos_tar->y - pos_src->y ); /* Within rescue basket pickup distance? */ /* Using target object's x bounds for now */ if((d - contact_radius - (cb_tar->contact_x_max - cb_tar->contact_x_min)) > 0.0f ) { need_break = True; break; } /* Is target object under the rescue basket? */ if((pos_tar->z + cb_tar->contact_z_max) < (pos_src->z + hoist->contact_z_min) ) { need_break = True; break; } break; } if(need_break) break; /* Put human object into the hoist deployment (if * possible) and update the human object to mark it * as no longer needing rescue */ if(SARSimDoPickUpHuman(scene, obj_ptr, human_ptr, tar_obj_num) > 0) { matched_obj_num = tar_obj_num; return(matched_obj_num); } break; 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; } } return(matched_obj_num); } searchandrescue_1.5.0/sar/sceneio.c0000644000175000017500000012143510104533035016320 0ustar jessejesse#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.5.0/sar/obj.h0000644000175000017500000015000711545425626015467 0ustar jessejesse/* SAR Objects and Scene */ #ifndef OBJ_H #define OBJ_H #include #include "sfm.h" #include "v3dtex.h" #include "sound.h" /* * Object Flags Type: */ #define sar_obj_flags_t unsigned long /* * Gradient Animation Counter Type: */ #define sar_grad_anim_t u_int16_t #define SAR_GRAD_ANIM_COEFF(x) ((float)(x) / (float)((sar_grad_anim_t)-1)) /* * DMS Units Type: */ #define sar_dms_t float /* * Time Of Day Codes: */ typedef enum { SAR_TOD_CODE_UNDEFINED, SAR_TOD_CODE_DAY, SAR_TOD_CODE_DAWN, SAR_TOD_CODE_NIGHT, SAR_TOD_CODE_DUSK } sar_tod_code; /* * Camera References: */ typedef enum { SAR_CAMERA_REF_COCKPIT, SAR_CAMERA_REF_SPOT, SAR_CAMERA_REF_TOWER, SAR_CAMERA_REF_MAP, SAR_CAMERA_REF_HOIST } sar_camera_ref; /* * Air Worthy States: */ typedef enum { SAR_AIR_WORTHY_NOT_FLYABLE, /* Pile of junk */ SAR_AIR_WORTHY_OUT_OF_CONTROL, SAR_AIR_WORTHY_FLYABLE } sar_air_worthy_state; /* * Engine States: */ typedef enum { SAR_ENGINE_OFF, SAR_ENGINE_INIT, SAR_ENGINE_ON } sar_engine_state; /* * Autopilot States: */ typedef enum { SAR_AUTOPILOT_OFF, SAR_AUTOPILOT_ON } sar_autopilot_state; /* * Human color palette index and max: */ #define SAR_HUMAN_COLOR_FACE 0 #define SAR_HUMAN_COLOR_HAIR 1 #define SAR_HUMAN_COLOR_TORSO 2 #define SAR_HUMAN_COLOR_HIPS 3 #define SAR_HUMAN_COLOR_LEGS 4 #define SAR_HUMAN_COLOR_FEET 5 #define SAR_HUMAN_COLOR_ARMS 6 #define SAR_HUMAN_COLOR_HANDS 7 #define SAR_HUMAN_COLORS_MAX 8 /* * Color: * * Each member must be of type float and their order is * important, units are in coefficients from 0.0 to 1.0. */ typedef struct { float r, g, b, a; } sar_color_struct; #define SAR_COLOR(p) ((sar_color_struct *)(p)) /* * Visual Model: * * Values for a GL display list with reference count feature that * allows other objects to share this visual model simply by * incrementing the ref_count. The GL display list pointer data * reffers to a GLuint. * * Members filename and name are used to identify if this visual * model should be shared or not by allowing you to check if * another object uses this same visual model. */ typedef enum { SAR_VISUAL_MODEL_NOT_LOADED, SAR_VISUAL_MODEL_LOADING, SAR_VISUAL_MODEL_LOADED } sar_visual_model_load_state; typedef struct { sar_visual_model_load_state load_state; int ref_count; /* Reference count */ char *filename; /* Can be NULL */ char *name; /* Can be NULL */ void *data; /* A GLuint referencing a GL list */ /* Statistics */ unsigned long mem_size; /* Memory size, in bytes */ int statements, /* Total GL statements */ primitives; /* Total GL primitives */ } sar_visual_model_struct; #define SAR_VISUAL_MODEL(p) ((sar_visual_model_struct *)(p)) /* * Position/Velocity: * * Each member must be of type float and their order is * important. * * When used as position the units are in meters, when used as * velocity the units are in meters per cycle. */ typedef struct { float x, y, z; } sar_position_struct; #define SAR_POSITION(p) ((sar_position_struct *)(p)) /* * Direction: * * Each member must be of type float and their order is * important, units are in radians. */ typedef struct { float heading, pitch, bank; } sar_direction_struct; #define SAR_DIRECTION(p) ((sar_direction_struct *)(p)) /* * Scale: * * Each member must be of type float and their order is * important, units are in coefficients. */ typedef struct { float x, y, z; } sar_scale_struct; #define SAR_SCALE(p) ((sar_scale_struct *)(p)) /* * Intercept: */ typedef struct { sar_obj_flags_t flags; /* Reserved */ float x, y, z; /* Center of intercept, in meters */ float radius; /* Cylendrical size of intercept, in meters */ float urgency; /* Specifies the "urgency" of which this * intercept must be reached (used for a * variety of purposes) */ char *name; /* Intercept name/label */ } sar_intercept_struct; #define SAR_INTERCEPT(p) ((sar_intercept_struct *)(p)) /* * Light: */ typedef struct { #define SAR_LIGHT_FLAG_ON (1 << 0) #define SAR_LIGHT_FLAG_STROBE (1 << 1) #define SAR_LIGHT_FLAG_ATTENUATE (1 << 2) sar_obj_flags_t flags; sar_position_struct pos; sar_direction_struct dir; int radius; /* In pixels */ sar_color_struct color, /* Appearance color */ attenuate_color; /* Attenuate color */ /* On/off timers (if the SAR_LIGHT_FLAG_STROBE flag is set) * in milliseconds */ time_t next_on, int_on, next_off, int_off; time_t int_delay_on; /* Additional interval to wait * before turning light on when * timer is reset */ } sar_light_struct; #define SAR_LIGHT(p) ((sar_light_struct *)(p)) /* * Contact Bounds: * * Note that any object can have contact bounds, but rules apply * to different object types. * * Objects of type SAR_OBJ_TYPE_HUMAN and SAR_OBJ_TYPE_AIRCRAFT * should only have crash flag SAR_CRASH_FLAG_CRASH_OTHER set and * it's contact shape must be SAR_CONTACT_SHAPE_CYLENDRICAL. * * Other objects that you want to set crash flag * SAR_CRASH_FLAG_CRASH_CAUSE can have any contact shape. * * Now objects that you want to be landable or walkable must have * crash flag SAR_CRASH_FLAG_SUPPORT_SURFACE set. * * If an object's crash flag has set * SAR_CRASH_FLAG_SUPPORT_SURFACE then the object can only have its * heading rotated. */ typedef enum { SAR_CRASH_TYPE_OBSTRUCTION, SAR_CRASH_TYPE_GROUND, SAR_CRASH_TYPE_MOUNTAIN, /* To be more specific than * just ground */ SAR_CRASH_TYPE_BUILDING, SAR_CRASH_TYPE_AIRCRAFT, /* Not used */ SAR_CRASH_TYPE_FIRE } sar_crash_type; typedef enum { SAR_CONTACT_SHAPE_SPHERICAL, SAR_CONTACT_SHAPE_CYLENDRICAL, SAR_CONTACT_SHAPE_RECTANGULAR } sar_contact_shape; typedef struct { #define SAR_CRASH_FLAG_CRASH_OTHER (1 << 0) /* Crash into or contact * other objects */ #define SAR_CRASH_FLAG_CRASH_CAUSE (1 << 1) /* Other objects can * crash into this * object */ #define SAR_CRASH_FLAG_SUPPORT_SURFACE (1 << 2) /* Landable/walkable */ sar_obj_flags_t crash_flags; /* Crash Type (used only if the Crash Flag * SAR_CRASH_FLAG_CRASH_CAUSE is set), this specifies what type * of crash it would be if an object crashed into this object */ sar_crash_type crash_type; /* Contact Shape */ sar_contact_shape contact_shape; /* Contact Radius (in meters) for Contact Shape * SAR_CONTACT_SHAPE_SPHERICAL or SAR_CONTACT_SHAPE_CYLENDRICAL */ float contact_radius; /* Contact Height (in meters) for Contact Shape * SAR_CONTACT_SHAPE_CYLENDRICAL */ float contact_h_min, contact_h_max; /* Contact Geometry (in meters, left hand rule) for Contact * Shape SAR_CONTACT_SHAPE_RECTANGULAR */ float contact_x_min, contact_x_max, contact_y_min, contact_y_max, contact_z_min, contact_z_max; /* Value records for the object's inversed heading for the trig * functions, this is used to speed up rotations about heading * for SAR_CONTACT_SHAPE_RECTANGULAR shape contact * * Ie cos_heading = cos(-heading) and sin_heading = sin(-heading) */ float cos_heading, sin_heading; } sar_contact_bounds_struct; #define SAR_CONTACT_BOUNDS(p) ((sar_contact_bounds_struct *)(p)) /* * Sound Source: */ typedef struct { char *name; /* Arbitary name to identify this * in a list of sound sources */ char *filename, /* Full path to sound object */ *filename_far; float range, /* Maximum range (in meters) */ range_far; /* Play far sound if beyond this * range (in meters) */ sar_position_struct pos; /* Offset from center of object */ float cutoff; /* Cutoff angle (in radians), * can be 0.0 to specify "in all * directions" */ sar_direction_struct dir; /* Direction, used only if cutoff * is positive */ /* Sample rate limit, the amount that the sample rate can * increase to * * For example if the sound object's sample rate is 11025 hz * and sample_rate_limit is 30000 hz, then the sound object's * sample rate can be increased from 11025 to 30000 hz */ int sample_rate_limit; } sar_sound_source_struct; #define SAR_SOUND_SOURCE(p) ((sar_sound_source_struct *)(p)) /* * Rotor/Propellar: */ typedef enum { SAR_ROTOR_FLAG_SPINS = (1 << 0), SAR_ROTOR_FLAG_CAN_PITCH = (1 << 1), SAR_ROTOR_FLAG_PITCH_STATE = (1 << 2), /* Set if pitched forward * (does not determine * flight model type) */ SAR_ROTOR_FLAG_NO_PITCH_LANDED = (1 << 3), /* May not pitch when * landed */ SAR_ROTOR_FLAG_FOLLOW_CONTROLS = (1 << 5), /* Pitches & banks in * response to control * positions */ SAR_ROTOR_FLAG_BLUR_WHEN_FAST = (1 << 8), /* Blur when spinning * fast */ SAR_ROTOR_FLAG_BLUR_ALWAYS = (1 << 9) /* Always blur (overrides * SAR_ROTOR_FLAG_BLUR_WHEN_FAST */ } sar_rotor_flags; typedef struct { sar_rotor_flags flags; sar_position_struct pos; /* Relative from center of object */ sar_direction_struct dir; /* Note: rotor spins about the Y axis */ float radius; /* Length of longest blade (in meters) */ float blades_offset; /* Blades offset from rotor (in meters) */ int total_blades; /* Number of blades */ sar_grad_anim_t anim_pos; /* Spin animation position */ sar_visual_model_struct *visual_model, *visual_model_ir; /* Rotor pitch rotate position (0 to (sar_grad_anim_t)-1), * where (sar_grad_anim_t)-1 is pitched forwards * (when SAR_ROTOR_FLAG_PITCH_STATE is set) */ sar_grad_anim_t pitch_anim_pos; /* Rotor wash animation position */ sar_grad_anim_t rotor_wash_anim_pos; int blade_blur_tex_num, /* Blured blade texture */ wash_tex_num; /* Prop wash texture */ /* Control position coefficients (used only if * SAR_ROTOR_FLAG_FOLLOW_PB is set) */ float control_coeff_pitch, control_coeff_bank; /* Blades blur color (used when blades are spinning fast) */ sar_color_struct blades_blur_color; } sar_obj_rotor_struct; #define SAR_OBJ_ROTOR(p) ((sar_obj_rotor_struct *)(p)) /* * Object Part: * * Flaps, ailerons, elevator, rudder, air brakes, landing gears, * canopies, etc */ typedef enum { SAR_OBJ_PART_TYPE_AILERON_LEFT, SAR_OBJ_PART_TYPE_AILERON_RIGHT, SAR_OBJ_PART_TYPE_RUDDER_TOP, SAR_OBJ_PART_TYPE_RUDDER_BOTTOM, SAR_OBJ_PART_TYPE_ELEVATOR, SAR_OBJ_PART_TYPE_CANNARD, /* Forward elevator */ SAR_OBJ_PART_TYPE_AILERON_ELEVATOR_LEFT, /* Combo */ SAR_OBJ_PART_TYPE_AILERON_ELEVATOR_RIGHT, /* Combo */ SAR_OBJ_PART_TYPE_FLAP, SAR_OBJ_PART_TYPE_AIR_BRAKE, SAR_OBJ_PART_TYPE_DOOR, SAR_OBJ_PART_TYPE_DOOR_RESCUE, SAR_OBJ_PART_TYPE_CANOPY, SAR_OBJ_PART_TYPE_LANDING_GEAR } sar_obj_part_type; typedef struct { sar_obj_part_type type; /* Part Flags (different part types may have the same part flag * values) */ #define SAR_OBJ_PART_FLAG_STATE (1 << 0) /* Set if opened/extended */ #define SAR_OBJ_PART_FLAG_HIDE_MIN (1 << 1) /* Hide when animation value is at min */ #define SAR_OBJ_PART_FLAG_HIDE_MAX (1 << 2) /* Hide when animation value is at max */ /* Doors, Rescue Doors, and Canopies */ #define SAR_OBJ_PART_FLAG_DOOR_FIXED (1 << 3) /* True if fixed (always closed) */ #define SAR_OBJ_PART_FLAG_DOOR_LOCKED (1 << 4) /* True if locked */ #define SAR_OBJ_PART_FLAG_DOOR_STAY_OPEN (1 << 5) /* Do not close door on * next loop check, * ie if door was opened by player explicitly */ /* Landing Gears */ #define SAR_OBJ_PART_FLAG_LGEAR_FIXED (1 << 3) /* Always down */ #define SAR_OBJ_PART_FLAG_LGEAR_DAMAGED (1 << 4) #define SAR_OBJ_PART_FLAG_LGEAR_MISSING (1 << 5) /* Non-existant */ #define SAR_OBJ_PART_FLAG_LGEAR_SKI (1 << 6) #define SAR_OBJ_PART_FLAG_LGEAR_FLOATS (1 << 7) /* Can land on water */ sar_obj_flags_t flags; /* Offset relative to center of object, pos_min and pos_max * are deltas relative to pos_cen * * Note that some part types interprite these values differently */ sar_position_struct pos_min, pos_cen, pos_max; /* Direction, dir_min and dir_max are deltas relative to * dir_cen * * Note that some part types interprite these values differently */ sar_direction_struct dir_min, dir_cen, dir_max; sar_grad_anim_t anim_pos, /* 0 to (sar_grad_anim_t)-1 */ anim_rate; /* Units per cycle */ float temperature; sar_visual_model_struct *visual_model, *visual_model_ir; } sar_obj_part_struct; #define SAR_OBJ_PART(p) ((sar_obj_part_struct *)(p)) /* * External Fuel Tank: * * This is a fuel tank that is on an object. * * See sar_object_fueltank_struct (which is a fuel tank object). */ typedef struct { #define SAR_EXTERNAL_FUELTANK_FLAG_FIXED (1 << 0) /* Not droppable */ #define SAR_EXTERNAL_FUELTANK_FLAG_ONBOARD (1 << 1) /* Not yet jettesoned */ sar_obj_flags_t flags; /* Offset from center of object, in meters */ sar_position_struct offset_pos; /* Spherical contact bounds radius, in meters */ float radius; /* Belly to center height, in meters */ float belly_to_center_height; /* Mass and fuel, in kg */ float dry_mass, fuel, fuel_max; float temperature; sar_visual_model_struct *visual_model, *visual_model_ir; } sar_external_fueltank_struct; #define SAR_EXTERNAL_FUELTANK(p) ((sar_external_fueltank_struct *)(p)) /* * Hoist: */ typedef enum { SAR_HOIST_DEPLOYMENT_BASKET = (1 << 0), SAR_HOIST_DEPLOYMENT_DIVER = (1 << 1), SAR_HOIST_DEPLOYMENT_HOOK = (1 << 2) } sar_hoist_deployment_flags; typedef struct { /* Offset from center of object */ sar_position_struct offset; /* Position (not offset) of basket */ sar_position_struct pos; /* Direction of basket */ sar_direction_struct dir; /* Rope extension (if <= 0.0 then implies the rope is fully * retracted) */ float rope_cur, /* In meters */ rope_max; float rope_rate; /* In meters per cycle */ /* Rope visual extension, since rope_cur may be longer than the * distance to the landable ground (in meters) we need to use * this value when drawing */ float rope_cur_vis; /* Indicates rope end is in contact with ground */ char on_ground; /* Hoist deployment */ sar_hoist_deployment_flags deployments, /* Available deployments */ cur_deployment; /* Selected deployment */ /* Cylendrical contact area of rescue basket, in meters */ float contact_radius, contact_z_min, contact_z_max; /* Load capacity, in kg */ float capacity; /* Reference to occupant human object index numbers (does not * include the diver) */ int *occupant; int total_occupants; /* Total mass of occupant object(s) in kg, this is to speed up * calculations. The value is updated when a new occupant object * is added to the hoist and reset to 0 when the hoist is deployed * the next time. */ float occupants_mass; /* Texture reference numbers on scene structure */ int side_tex_num, end_tex_num, bottom_tex_num, water_ripple_tex_num; /* Diver color palette */ sar_color_struct diver_color[SAR_HUMAN_COLORS_MAX]; /* Animation position and rate */ sar_grad_anim_t anim_pos, anim_rate; } sar_obj_hoist_struct; #define SAR_OBJ_HOIST(p) ((sar_obj_hoist_struct *)(p)) /* * Object Types: */ typedef enum { SAR_OBJ_TYPE_GARBAGE = 0, SAR_OBJ_TYPE_STATIC = 1, SAR_OBJ_TYPE_AUTOMOBILE = 2, SAR_OBJ_TYPE_WATERCRAFT = 3, SAR_OBJ_TYPE_AIRCRAFT = 4, /* Note type 5 used to be airplane, it's now changed to be part of * type 4 (which was helicopter) so both 4 and 5 are all flying things * now */ SAR_OBJ_TYPE_GROUND = 6, /* Cylendrical landable object */ SAR_OBJ_TYPE_RUNWAY = 7, SAR_OBJ_TYPE_HELIPAD = 8, SAR_OBJ_TYPE_HUMAN = 9, SAR_OBJ_TYPE_SMOKE = 10, SAR_OBJ_TYPE_FIRE = 11, SAR_OBJ_TYPE_EXPLOSION = 12, SAR_OBJ_TYPE_CHEMICAL_SPRAY = 13, /* Water, fire-retardant, etc */ SAR_OBJ_TYPE_FUELTANK = 14, /* Fuel tank dropped from an * aircraft */ SAR_OBJ_TYPE_PREMODELED = 20 } sar_obj_type; /* * Object Type Check macros: */ #define SAR_OBJ_IS_STATIC(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_STATIC) : 0) #define SAR_OBJ_IS_AUTOMOBILE(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_AUTOMOBILE) : 0) #define SAR_OBJ_IS_WATERCRAFT(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_WATERCRAFT) : 0) #define SAR_OBJ_IS_AIRCRAFT(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_AIRCRAFT) : 0) #define SAR_OBJ_IS_GROUND(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_GROUND) : 0) #define SAR_OBJ_IS_RUNWAY(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_RUNWAY) : 0) #define SAR_OBJ_IS_HELIPAD(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_HELIPAD) : 0) #define SAR_OBJ_IS_HUMAN(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_HUMAN) : 0) #define SAR_OBJ_IS_SMOKE(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_SMOKE) : 0) #define SAR_OBJ_IS_FIRE(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_FIRE) : 0) #define SAR_OBJ_IS_EXPLOSION(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_EXPLOSION) : 0) #define SAR_OBJ_IS_CHEMICAL_SPRAY(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_CHEMICAL_SPRAY) : 0) #define SAR_OBJ_IS_FUELTANK(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_FUELTANK) : 0) #define SAR_OBJ_IS_PREMODELED(p) \ (((p) != NULL) ? ((*(sar_obj_type *)(p)) == SAR_OBJ_TYPE_PREMODELED) : 0) /* * Object Type Substructure Pointer Get macros: * * These macros will return a pointer to the substructure (member * data) with cast or NULL if the given object pointer is NULL or * not of the corresponding type. */ #define SAR_OBJ_GET_STATIC(p) \ (sar_object_static_struct *)((SAR_OBJ_IS_STATIC(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_AIRCRAFT(p) \ (sar_object_aircraft_struct *)((SAR_OBJ_IS_AIRCRAFT(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_GROUND(p) \ (sar_object_ground_struct *)((SAR_OBJ_IS_GROUND(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_RUNWAY(p) \ (sar_object_runway_struct *)((SAR_OBJ_IS_RUNWAY(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_HELIPAD(p) \ (sar_object_helipad_struct *)((SAR_OBJ_IS_HELIPAD(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_HUMAN(p) \ (sar_object_human_struct *)((SAR_OBJ_IS_HUMAN(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_SMOKE(p) \ (sar_object_smoke_struct *)((SAR_OBJ_IS_SMOKE(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_FIRE(p) \ (sar_object_fire_struct *)((SAR_OBJ_IS_FIRE(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_EXPLOSION(p) \ (sar_object_explosion_struct *)((SAR_OBJ_IS_EXPLOSION(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_CHEMICAL_SPRAY(p) \ (sar_object_chemical_spray_struct *)((SAR_OBJ_IS_CHEMICAL_SPRAY(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_FUELTANK(p) \ (sar_object_fueltank_struct *)((SAR_OBJ_IS_FUELTANK(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) #define SAR_OBJ_GET_PREMODELED(p) \ (sar_object_premodeled_struct *)((SAR_OBJ_IS_PREMODELED(p)) ? \ ((sar_object_struct *)(p))->data : NULL \ ) /* * Aircraft: */ typedef enum { SAR_FLIGHT_MODEL_HELICOPTER, SAR_FLIGHT_MODEL_AIRPLANE, SAR_FLIGHT_MODEL_SLEW } sar_flight_model_type; typedef struct { /* Flight Model Type */ sar_flight_model_type flight_model_type; /* Previously set Flight Model Type (for switching back and * forth between flight model types */ sar_flight_model_type last_flight_model_type; /* Flight Dynamics Model */ SFMModelStruct *fdm; /* Air Worthy State */ sar_air_worthy_state air_worthy_state; /* Current speed, in meters per cycle */ float speed; /* Stall speed, the speed at which a controllable stall begins. * Loss of lift can still occure twice beyond this value, in * meters per cycle */ float speed_stall, stall_coeff; /* Maximum speed (this is typically *several* times the rated * maximum speed), in meters per cycle */ float speed_max; /* overspeed_expected is the overspeed value according to the * specifications of the aircraft, if the speed reaches or * exceeds this value then overspeed warnings and affects are * performed, units are in meters per cycle * * overspeed is the speed at which the aircraft will incure * damage, in meters per cycle */ float overspeed_expected, overspeed; /* Current velocity vector representing velocity in object * relative vector direction, in meters per cycle */ sar_position_struct vel; /* Z acceleration, in meters per cucle^2 */ float z_accel; /* Minimum drag in meters per cycle, must be non-negative */ float min_drag; /* Acceleration response for when flight_model_type is set to * SAR_FLIGHT_MODEL_HELICOPTER, higher values produce less * responsiveness) * * Note: This should really be called be accel dampening */ sar_position_struct accel_responsiveness; /* Acceleration response for when flight_model_type is set to * SAR_FLIGHT_MODEL_AIRPLANE, higher values produce less * responsiveness) * * Note: This should really be called be accel dampening */ sar_position_struct airplane_accel_responsiveness; /* Attitude change rates, in radians per cycle */ sar_direction_struct attitude_change_rate; /* Pitch and bank leveling, in radians per cycle */ float pitch_leveling, bank_leveling; /* Ground pitch offset in radians (can be negative) */ float ground_pitch_offset; /* Cockpit offset relative to object center */ sar_position_struct cockpit_offset_pos; /* Cockpit visual model */ sar_visual_model_struct *visual_model_cockpit; /* Belly to center of object in meters */ float belly_height; /* Height of landing gear in meters */ float gear_height; /* Mass */ float dry_mass; /* In kg */ float fuel_rate; /* In kg consumed per cycle */ float fuel, fuel_max; /* In kg */ int crew, passengers, passengers_max; float passengers_mass; /* Total mass of current * passengers (in kg) */ /* Passengers pending to leave or drop from this aircraft, * 0 means none and any positive value means this many passengers * need to go when the aircraft's door is fully opened and its * conditions are right (ie landed at the right helipad) */ int passengers_leave_pending, passengers_drop_pending; /* External fuel tanks */ sar_external_fueltank_struct **external_fueltank; int total_external_fueltanks; /* Engine state and control positions */ sar_engine_state engine_state; time_t next_engine_on; /* Time till engine starts up (in ms) */ /* Throttle control position. In aircraft flight model this is * the actual throttle control position, in helicopter flight * model this is the speed at which the rotors are spinning. * Range is from 0.0 to 1.0 */ float throttle; /* Current collective value and collective range. The current * collective value is always 1.0 in airplane flight model. In * helicopter flight model, the current collective value matches * the game controller's throttle position * * Both the collective and collective_range are in values from * 0.0 to 1.0 */ float collective, collective_range; /* Engine data */ float engine_power; /* In kg * m / cycle^2 */ char engine_can_pitch; /* 1 for tilt rotors */ /* Engine sounds */ int engine_inside_sndsrc; void *engine_inside_sndplay; int engine_outside_sndsrc; void *engine_outside_sndplay; /* Repeating warning sounds */ int stall_sndsrc; void *stall_sndplay; int overspeed_sndsrc; void *overspeed_sndplay; /* Visual controller positions, these values only dictate * the visual display of control parts */ float control_heading, /* Rudder, -1.0 to 1.0 */ control_pitch, /* Elevator, -1.0 to 1.0 */ control_bank; /* Ailerons, -1.0 to 1.0 */ /* Effective controller positions, these values will be passed * to the FDM and control the actual attitude changing */ float control_effective_heading, /* Rudder, -1.0 to 1.0 */ control_effective_pitch, /* Elevator, -1.0 to 1.0 */ control_effective_bank; /* Ailerons, -1.0 to 1.0 */ float elevator_trim; /* -1.0 to 1.0 */ /* Flaps */ float flaps_position; /* 0.0 (retracted) to 1.0 * (fully deployed) */ float flaps_stall_offset; /* Moves the speed_stall * ahead by this many * meters per cycle */ /* Service ceiling, in meters */ float service_ceiling; /* Distance from object's center to touchable ground in meters * (note that this is usually negative unless the object is * underground) */ float center_to_ground_height; /* Moveable parts */ sar_obj_part_struct **part; int total_parts; /* Rotors */ sar_obj_rotor_struct **rotor; int total_rotors; /* Landed states */ char landed, /* 1 if landed */ on_water; /* If landed is 1 and on_water is 1, * then is on water */ /* Landing gear state: * -1 non-existant * 0 up/retracted/in * 1 down/deployed/out */ int landing_gear_state; /* Ground turning */ float gturn_radius; /* Distance from farthest non-turning * gear to turning gear in meters, can * be negative (0 implies no turning) */ /* Ground turning velocity optimul and maximum (meters per * cycle) */ float gturn_vel_opt, gturn_vel_max; /* Air brakes and wheel brakes: * -1 non-existant * 0 off * 1 on * 2 locked (parking brakes on) */ int air_brakes_state, wheel_brakes_state; /* Air brake affect on speed, in units of meters per cycle * Can be 0.0 if this aircraft has no air brakes * The affect of the air brakes will be at its maximum * (the exact value of air_brakes_rate) when the speed * approaches speed_max_expected. As the speed reduces to * speed_stall the affect of air_brakes_rate will be reduced * to 10% and as the speed reduces to 0 the affect of * air_brakes_rate will be 0% */ float air_brakes_rate; /* Spot light direction */ sar_direction_struct spotlight_dir; /* Rescue hoist */ sar_obj_hoist_struct *hoist; /* Intercept waypoints */ sar_intercept_struct **intercept; int total_intercepts, cur_intercept; /* Autopilot data */ sar_autopilot_state autopilot_state; float autopilot_altitude; /* Target height in meters * above sea level */ } sar_object_aircraft_struct; #define SAR_OBJECT_AIRCRAFT(p) ((sar_object_aircraft_struct *)(p)) /* * Ground/Heightfield: */ typedef struct { /* Elevation from (above) local MSL in meters. If MSL was * set to 10 meters and this elevation was set to 3 meters then * the resulting elevation would be 13 meters to any object within * contact of the ground object. * * Note that the ground object itself completely ignores the * scene structure defined ground_elevation_msl value. */ float elevation; /* Translation of heightfield from center of object */ float x_trans, y_trans, z_trans; /* Heightfield data (only used if z_point_value is not NULL) */ float x_len, /* grid_points_x * grid_x_spacing */ y_len; /* grid_points_y * grid_y_spacing */ int grid_points_x, /* Number of grid points */ grid_points_y, grid_points_total; /* grid_points_x * grid_points_y */ float grid_x_spacing, /* Size of each grid in meters */ grid_y_spacing, grid_z_spacing; double *z_point_value; /* Heightfield z height map, each * point value came from * (image_data_pixel) / * 0xff * grid_z_spacing */ /* Value records for this ground object's inversed heading for the * trig functions, this is used to speed up rotations of heading * for checking an object over this ground object's heightfield * surface. It also limits ground objects to only have its * heading rotated. * * Ie cos_heading = cos(-heading) and sin_heading = sin(-heading) */ float cos_heading, sin_heading; } sar_object_ground_struct; #define SAR_OBJECT_GROUND(p) ((sar_object_ground_struct *)(p)) /* * Smoke Puffs & Sparks: */ typedef enum { SAR_SMOKE_TYPE_SMOKE, SAR_SMOKE_TYPE_SPARKS, SAR_SMOKE_TYPE_DEBRIS } sar_smoke_type; /* Smoke Puff & Sparks Units */ typedef struct { sar_position_struct pos; /* In world coordinates */ sar_position_struct vel; /* Color, only used when the smoke type is set to * SAR_SMOKE_TYPE_SPARKS */ sar_color_struct color; /* Current size in meters */ float radius; /* Current visibility of smoke unit, in range of 0.0 to 1.0. * If 0.0 then it will not be drawn at all and is considered * "available for use" */ float visibility; } sar_object_smoke_unit_struct; /* Smoke/Sparks */ typedef struct { sar_smoke_type type; /* Spawn offset position, this offset is applied to the actual * location of the smoke trail object where each unit will be * spawned at */ sar_position_struct respawn_offset; /* Starting and ending radius values for all units * * If the smoke type is SAR_OBJ_SMOKE_TYPE_SPARKS then * radius_start is ignored and radius_max is how far sparks * should fly */ float radius_start, radius_max; /* Radius increase rate in meters per cycle (must be positive) * * If the smoke type is SAR_OBJ_SMOKE_TYPE_SPARKS then this * value is ignored */ float radius_rate; /* If this is true then when a smoke unit has reached its * maximum size its visiblity will be reset to 0.0 (thus marking * it as "available for use") */ int hide_at_max; /* If this is true then this object will be marked for deletion * (its life span set to 1) when all of its units are no longer * visible (visibility = 0.0) */ int delete_when_no_units; /* Respawn intervals (in ms) * * If respawn_int is 0 then no respawning will take place * * This is often used to stop respawning but keep the already * visible smoke units around */ time_t respawn_int, respawn_next; /* Texture number on scene structure */ int tex_num; /* Reference object that this smoke trail is to follow (can be -1 * for none or do not follow) */ int ref_object; /* Each smoke unit forming this smoke trail */ sar_object_smoke_unit_struct *unit; int total_units; } sar_object_smoke_struct; #define SAR_OBJECT_SMOKE_UNIT(p) ((sar_object_smoke_unit_struct *)(p)) #define SAR_OBJECT_SMOKE(p) ((sar_object_smoke_struct *)(p)) /* * Explosion/Splash: */ typedef enum { SAR_EXPLOSION_COLOR_EMISSION_NONE, /* Interacts with light (ie splashes) */ SAR_EXPLOSION_COLOR_EMISSION_IS_LIGHT, /* Does not interact with light */ SAR_EXPLOSION_COLOR_EMISSION_EMIT_LIGHT /* Gives off light */ } sar_explosion_color_emission; typedef enum { SAR_EXPLOSION_CENTER_OFFSET_NONE, SAR_EXPLOSION_CENTER_OFFSET_BASE } sar_explosion_center_offset; typedef struct { /* Spherical size of the explosion (in meters), this is also * used to calculate the displayed explosion billboard */ float radius; sar_explosion_color_emission color_emission; sar_explosion_center_offset center_offset; time_t frame_inc_int, /* Frame increment interval (in ms) */ next_frame_inc; /* Time to increment next frame (in ms) */ int cur_frame, /* Current frame */ frame_repeats; /* Number of times animation has cycled */ /* Number of frame repeats, 0 or less to repeat forever (or * when life span has exceeded) */ int total_frame_repeats; /* Texture number on scene */ int tex_num, ir_tex_num; /* Reference object that this explosion is to follow (can be * -1 for none/do not follow) */ int ref_object; } sar_object_explosion_struct; #define SAR_OBJECT_EXPLOSION(p) ((sar_object_explosion_struct *)(p)) /* * Fire: */ typedef struct { /* Cylendrical size of fire in meters, this is also used to * calculate the fire billboard * * Center is at the base of the fire */ float radius, height; time_t frame_inc_int, /* Frame increment interval, in ms */ next_frame_inc; /* Time to increment next frame, in ms */ int cur_frame, /* Current frame */ frame_repeats; /* Number of times animation has cycled */ /* Number of frame repeats, 0 or less to repeat forever (or * when life span has exceeded) */ int total_frame_repeats; /* Texture number on scene */ int tex_num, ir_tex_num; /* Reference object that this fire is to follow (can be -1 for * none/do not follow) */ int ref_object; } sar_object_fire_struct; #define SAR_OBJECT_FIRE(p) ((sar_object_fire_struct *)(p)) /* * Chemical Spray: * * A single puff of chemical spray (ie water, fire-retardant, etc). */ typedef enum { SAR_CHEMICAL_WATER, SAR_CHEMICAL_FIRE_RETARDANT } sar_chemical_type; typedef struct { sar_chemical_type chemical_type; int owner; /* Object that created this spray or -1 * for none */ /* Texture number on the scene */ int tex_num; } sar_object_chemical_spray_struct; #define SAR_OBJECT_CHEMICAL_SPRAY(p) ((sar_object_chemical_spray_struct *)(p)) /* * Fuel Tank: * * Note: This is not a fuel tank that is currently on an aircraft, * do not confuse this with the fuel tanks on objects (see * sar_external_fueltank_struct). */ typedef enum { SAR_FUELTANK_FLAG_ON_GROUND = (1 << 0) } sar_fueltank_flags; typedef struct { sar_fueltank_flags flags; /* Current speed in meters per cycle */ float speed; /* Maximum negative vertical velocity in meters per cycle */ float vel_z_max; /* Current velocity vector representing velocity in object * relative vector direction, in meters per cycle */ sar_position_struct vel; /* Belly to center height, in meters */ float belly_to_center_height; /* Index of object of which this fuel tank fell off of (can be * -1 for unknown) */ int ref_object; /* Mass and fuel (in kg) */ float dry_mass, fuel, fuel_max; } sar_object_fueltank_struct; #define SAR_OBJECT_FUELTANK(p) ((sar_object_fueltank_struct *)(p)) /* * Runway: */ typedef enum { SAR_RUNWAY_FLAG_THRESHOLDS = (1 << 0), /* Thresholds (not * Displaced Thresholds) */ SAR_RUNWAY_FLAG_BORDERS = (1 << 1), /* Side Borders */ SAR_RUNWAY_FLAG_TD_MARKERS = (1 << 2), /* Touch Down Markers */ SAR_RUNWAY_FLAG_MIDWAY_MARKERS = (1 << 3), SAR_RUNWAY_FLAG_NORTH_GS = (1 << 4), /* North Glide Slope */ SAR_RUNWAY_FLAG_SOUTH_GS = (1 << 5) /* South Glide Slope */ } sar_runway_flags; typedef enum { SAR_RUNWAY_SURFACE_PAVED, SAR_RUNWAY_SURFACE_GRAVEL, SAR_RUNWAY_SURFACE_CONCRETE, SAR_RUNWAY_SURFACE_GROVED } sar_runway_surface_type; typedef enum { SAR_RUNWAY_APPROACH_LIGHTING_END = (1 << 0), SAR_RUNWAY_APPROACH_LIGHTING_TRACER = (1 << 1), SAR_RUNWAY_APPROACH_LIGHTING_ALIGN = (1 << 2), SAR_RUNWAY_APPROACH_LIGHTING_ILS_GLIDE = (1 << 3) } sar_runway_approach_lighting_flags; typedef struct { sar_runway_flags flags; /* Size (in meters) */ float length, width; /* Surface Type */ sar_runway_surface_type surface_type; /* End Labels */ char *north_label, *south_label; sar_visual_model_struct *north_label_vmodel, *south_label_vmodel; float north_label_width, south_label_width; /* Number of dashes (0 for none) */ int dashes; /* Edge lighting in meters (0.0 for none) */ float edge_light_spacing; /* Approach lighting flags */ sar_runway_approach_lighting_flags north_approach_lighting_flags, south_approach_lighting_flags; sar_grad_anim_t tracer_anim_pos, tracer_anim_rate; /* Displaced threshold offset from respective edges in meters * (can be 0.0 for none) */ float north_displaced_threshold, south_displaced_threshold; sar_visual_model_struct *threshold_vmodel, *td_marker_vmodel, *midway_marker_vmodel, *north_displaced_threshold_vmodel, *south_displaced_threshold_vmodel; /* Runway background texture number (on scene structure) */ int tex_num; } sar_object_runway_struct; #define SAR_OBJECT_RUNWAY(p) ((sar_object_runway_struct *)(p)) /* * Helipad: */ typedef enum { SAR_HELIPAD_FLAG_LABEL = (1 << 1), SAR_HELIPAD_FLAG_EDGE_LIGHTING = (1 << 2), SAR_HELIPAD_FLAG_FUEL = (1 << 3), SAR_HELIPAD_FLAG_REPAIR = (1 << 4), SAR_HELIPAD_FLAG_DROPOFF = (1 << 5), /* Can drop * off passengers */ SAR_HELIPAD_FLAG_REF_OBJECT = (1 << 6), /* Has ref object */ SAR_HELIPAD_FLAG_FOLLOW_REF_OBJECT = (1 << 7), SAR_HELIPAD_FLAG_RESTART_POINT = (1 << 8) /* Is a restarting * point */ } sar_helipad_flags; typedef enum { SAR_HELIPAD_STYLE_GROUND_PAVED, SAR_HELIPAD_STYLE_GROUND_BARE, /* Unpaved */ SAR_HELIPAD_STYLE_BUILDING, /* Roof top */ SAR_HELIPAD_STYLE_VEHICLE /* On a vehicle or vessel */ } sar_helipad_style; typedef struct { sar_helipad_flags flags; sar_helipad_style style; /* Size of landable area (in meters) */ float length, width; /* Downward recession from the helipad's landable surface into * the ground (in meters) * * Example, a value of 2 means 2 meters down */ float recession; /* Label */ char *label; sar_visual_model_struct *label_vmodel; float label_width; /* Lighting edge spacing, in meters */ float light_spacing; /* Texture number on scene structure, specifying the texture * for the helipad's main landable area */ int tex_num; /* If SAR_HELIPAD_FLAG_REF_OBJECT is set then these members * will have affect * * Note: ref_offset is applied before ref_dir */ int ref_object; /* Object that this helipad `follows' */ sar_position_struct ref_offset; /* Relative to ref_object */ sar_direction_struct ref_dir; /* Relative to ref_object */ } sar_object_helipad_struct; #define SAR_OBJECT_HELIPAD(p) ((sar_object_helipad_struct *)(p)) /* * Human/Actor: */ typedef enum { SAR_HUMAN_FLAG_NEED_RESCUE = (1 << 1), SAR_HUMAN_FLAG_SIT = (1 << 2), /* Base at tush */ SAR_HUMAN_FLAG_SIT_DOWN = (1 << 3), /* Base at tush, feet * out forward */ SAR_HUMAN_FLAG_SIT_UP = (1 << 4), /* Base at feet */ SAR_HUMAN_FLAG_LYING = (1 << 5), SAR_HUMAN_FLAG_ALERT = (1 << 6), /* Is awake */ SAR_HUMAN_FLAG_AWARE = (1 << 7), /* Knows of surroundings */ SAR_HUMAN_FLAG_IN_WATER = (1 << 8), SAR_HUMAN_FLAG_ON_STREATCHER = (1 << 9), SAR_HUMAN_FLAG_RUN = (1 << 10), /* Animate as running */ SAR_HUMAN_FLAG_RUN_TOWARDS = (1 << 11), /* Intends to run towards * (does not imply currently * running */ SAR_HUMAN_FLAG_RUN_AWAY = (1 << 12), /* Intends to run away * (does not imply currently * running */ SAR_HUMAN_FLAG_PUSHING = (1 << 13), SAR_HUMAN_FLAG_GRIPPED = (1 << 14), /* Someone/something is * holding this (ie in * rescue basket */ SAR_HUMAN_FLAG_DIVER_CATCHER = (1 << 15) } sar_human_flags; typedef struct { sar_human_flags flags; float mass; /* In kg */ float height; /* In meters */ sar_grad_anim_t anim_pos, anim_rate; /* Colors, see definations for SAR_HUMAN_COLOR_* and * SAR_HUMAN_COLORS_MAX for index positions and maximum colors * (respectivly) */ sar_color_struct color[SAR_HUMAN_COLORS_MAX]; /* Water ripples texture number on the scene */ int water_ripple_tex_num; /* Reference to object running towards or away from, the following * values have special meaning: * * -1 No intercepting * -2 Intercept player * * Works when flags SAR_HUMAN_FLAG_RUN_TOWARDS xor * SAR_HUMAN_FLAG_RUN_AWAY is set and intercepting_object is * valid and not the human object itself. */ int intercepting_object; /* Distance to intercepting object in meters (may be ignored if * intercepting_object is -1. */ float intercepting_object_distance2d, intercepting_object_distance3d; /* Number of assisting humans following this human (0 for none). * these are not other objects but rather groups of humans drawn * with this human object to make it look like multiple * humans. */ int assisting_humans; sar_color_struct assisting_human_color[SAR_HUMAN_COLORS_MAX]; /* Messages */ char *mesg_enter; /* Entering into aircraft or vehicle */ } sar_object_human_struct; #define SAR_OBJECT_HUMAN(p) ((sar_object_human_struct *)(p)) /* * Premodeled Object: */ typedef enum { SAR_OBJ_PREMODELED_BUILDING, SAR_OBJ_PREMODELED_CONTROL_TOWER, SAR_OBJ_PREMODELED_HANGAR, SAR_OBJ_PREMODELED_POWER_TRANSMISSION_TOWER, SAR_OBJ_PREMODELED_TOWER, SAR_OBJ_PREMODELED_RADIO_TOWER } sar_premodeled_type; typedef struct { sar_premodeled_type type; /* Values, depending on type, not all may be applicateable */ float width, length, height; /* Animation */ sar_grad_anim_t anim_pos, anim_rate; /* Reference to a texture on the scene */ #define SAR_OBJ_PREMODEL_MAX_TEXTURES 10 int tex_num[SAR_OBJ_PREMODEL_MAX_TEXTURES]; } sar_object_premodeled_struct; #define SAR_OBJECT_PREMODELED(p) ((sar_object_premodeled_struct *)(p)) /* * SAR Object Core: */ typedef struct { sar_obj_type type; #define SAR_OBJ_FLAG_NO_DEPTH_TEST (1 << 1) #define SAR_OBJ_FLAG_HIDE_DAY_MODEL (1 << 2) /* Hide day model when not day */ #define SAR_OBJ_FLAG_HIDE_DAWN_MODEL (1 << 3) /* Hide dawn model when not dawn */ #define SAR_OBJ_FLAG_HIDE_DUSK_MODEL (1 << 4) /* Hide dusk model when not dusk */ #define SAR_OBJ_FLAG_HIDE_NIGHT_MODEL (1 << 5) /* Hide night model when not night */ /* These two only work if SAR_OBJ_FLAG_HIDE_NIGHT_MODEL is set */ #define SAR_OBJ_FLAG_NIGHT_MODEL_AT_DAWN (1 << 6) /* Show night modem at dawn */ #define SAR_OBJ_FLAG_NIGHT_MODEL_AT_DUSK (1 << 7) /* Show night modem at dusk */ #define SAR_OBJ_FLAG_SHADE_MODEL_SMOOTH (1 << 8) /* Use smooth shading */ #define SAR_OBJ_FLAG_FAR_MODEL_DAY_ONLY (1 << 9) /* Display far model during * time only. */ #define SAR_OBJ_FLAG_POLYGON_OFFSET (1 << 10) /* Enable polygon offset */ #define SAR_OBJ_FLAG_POLYGON_OFFSET_REVERSE (1 << 11) /* Same as SAR_OBJ_FLAG_POLYGON_OFFSET * cept offsets in * the other direction. */ #define SAR_OBJ_FLAG_POLYGON_OFFSET_WRITE_DEPTH (1 << 12) /* Write depth if * polygon offsetting. */ sar_obj_flags_t flags; /* Name of object (can be NULL) */ char *name; /* Current position and direction */ sar_position_struct pos; sar_direction_struct dir; /* Visible range of this object, in meters * * Object is not displayed when the camera is farther is beyond * this range */ float range; /* Visible range for displaying the far visual model when the * camera is beyond this range, in meters */ float range_far; /* Distance from sea level to touchable ground under object, in * meters (ignored for objects of type SAR_OBJ_TYPE_GROUND) */ float ground_elevation_msl; /* Contact bounds */ sar_contact_bounds_struct *contact_bounds; /* Time stamp of when this object was created in milliseconds * and in systime seconds (respectivly). The value in milliseconds * may not be accurate when timmers are reset */ time_t birth_time_ms, birth_time_sec; /* When this object `dies' (0 if lives forever) */ time_t life_span; /* Hit points */ float hit_points, hit_points_max; /* Temperature for FLIR (0.0 to 1.0) */ float temperature; /* Visual models */ sar_visual_model_struct *visual_model, /* Day */ *visual_model_ir, /* InfraRed */ *visual_model_far, /* Far */ *visual_model_dawn, /* Dawn */ *visual_model_dusk, /* Dusk */ *visual_model_night, /* Night */ *visual_model_shadow; /* Shadow */ /* Lights */ sar_light_struct **light; int total_lights; /* Sound sources */ sar_sound_source_struct **sndsrc; int total_sndsrcs; /* Pointer to additional data specific to the object type, * the structure's type is specified by this structure's member * type */ void *data; } sar_object_struct; #define SAR_OBJECT(p) ((sar_object_struct *)(p)) /* * Scene Ground Base: * * Contains visual models and tiling values for displaying of the * ground base. */ typedef struct { /* Note, ground base moves with camera in modulous increments * of the tiled width and height */ /* Tiling size, in meters */ int tile_width, tile_height; /* Tiling limited to this range from origin, in meters */ float close_range; /* Simple (far) solid color base plane and visual model */ sar_color_struct color; sar_visual_model_struct *visual_model_simple; /* Close up texture tiled base plane visual model */ sar_visual_model_struct *visual_model_close; } sar_scene_base_struct; #define SAR_SCENE_BASE(p) ((sar_scene_base_struct *)(p)) /* * Scene Horizon: */ typedef struct { /* Records the last time of day since midnight from the scene * in units of 5 minute intervals as a whole number for horizon * texture regeneration, see SARSimUpdateScene() in simmanage.c * for when and how this value is updated */ int last_tod; /* Gradient textures, 0 is most highlighted and * total_textures - 1 is darkest */ v3d_texture_ref_struct **texture; int total_textures; } sar_scene_horizon_struct; #define SAR_SCENE_HORIZON(p) ((sar_scene_horizon_struct *)(p)) /* * Scene Cloud Layer: * * Flat tiled layer of clouds as tiled textured quads. */ typedef struct { /* Note, cloud layer moves with camera in modulous * of the tiled width and height on the XY plane */ /* Tiling size, in meters */ int tile_width, tile_height; /* Tiling limited to this range from origin of tiling, in * meters */ float range; /* Name of cloud texture on scene structure */ char *tex_name; sar_visual_model_struct *visual_model; /* Height from MSL, in meters */ float z; } sar_cloud_layer_struct; #define SAR_CLOUD_LAYER(p) ((sar_cloud_layer_struct *)(p)) /* * Scene Cloud Billboard: */ typedef struct { /* Note, cloud billboard moves with camera in modulous of the * tiled width and height on the XY plane */ /* Tiling size, in meters */ int tile_width, tile_height; /* Name of texture on scene structure */ char *tex_name; /* Matched texture on scene structure */ int tex_num; /* Position of billboard object relative to tiled center */ sar_position_struct pos; /* Size of cloud object, in meters */ float width, height; /* Lightening timers, in ms * * If lightening_min_int and lightening_max_int are 0 then * that means there is no lightening */ time_t lightening_min_int, /* Minimum off interval */ lightening_max_int, /* Maximum off interval */ lightening_next_on, /* Waiting to go on */ lightening_next_off, /* Waiting to go off */ lightening_started_on; /* When turned on */ /* Lightening points relative to cloud billboard's center, * in meters */ #define SAR_LIGHTENING_POINTS_MAX 6 sar_position_struct lightening_point[SAR_LIGHTENING_POINTS_MAX]; } sar_cloud_bb_struct; #define SAR_CLOUD_BB(p) ((sar_cloud_bb_struct *)(p)) /* * Scene: */ typedef enum { SAR_SCENE_BASE_FLAG_IS_WATER = (1 << 1) /* All of the base is water */ } sar_scene_base_flags; typedef struct { /* Title of scenery */ char *title; /* Time of day (in seconds) since midnight */ float tod; /* Time Of Day Code, updated in SARSimUpdateScene() */ sar_tod_code tod_code; /* Ground Base Flags */ sar_scene_base_flags base_flags; /* CANT angle in radians, this value is only applied on readouts * added to the internal angle value in question */ float cant_angle; /* MSL elevation in meters */ float msl_elevation; /* GPS information */ sar_dms_t dms_x_offset, /* In degrees, -140.0 to 140.0 */ dms_y_offset; /* In degrees, -90.0 to 90.0 */ float planet_radius; /* In meters */ /* Visual Models List, each object's Visual Models are recorded * here in this list and only these Visual Models may be deleted */ sar_visual_model_struct **visual_model; int total_visual_models; /* Sky and horizon gradient colors */ sar_color_struct sky_nominal_color, sky_brighten_color, sky_darken_color; /* Celestial object colors, these colors define the low and high * tint colors of the celestial object (where low means it is near * the horizon). */ sar_color_struct star_low_color, star_high_color, sun_low_color, sun_high_color, moon_low_color, moon_high_color; /* Position of sun is dirived from light_pos */ /* Moon position, a unit vector to be applied to the camera * position */ sar_position_struct moon_pos; /* Moon visibility hint, 1 = above horizon, 0 = hidden */ char moon_visibility_hint; /* Atmosphere (when enabled) */ float atmosphere_dist_coeff, /* Coeff * max visiblity */ atmosphere_density_coeff; /* Rain density coefficient, 0.0 for no rain, 0.5 for moderate, * 1.0 for densest rain */ float rain_density_coeff; /* Reference to player object */ int player_obj_num; sar_object_struct *player_obj_ptr; char player_has_crashed; /* 1 if player object has crashed */ /* Pointers to SAR_OBJ_TYPE_GROUND objects, you may free * the pointer array but not the pointer to structures!! */ sar_object_struct **ground_object; int total_ground_objects; /* Pointers to SAR_OBJ_TYPE_HUMAN objects that *need rescue*. * You may free the pointer array but not the pointers to structures!! */ sar_object_struct **human_need_rescue_object; int total_human_need_rescue_objects; /* Camera reference */ sar_camera_ref camera_ref; /* Camera field of view, in radians along Z axis (about the * the X axis) */ float camera_fovz; /* Direction of camera (when camera_ref=SAR_CAMERA_REF_COCKPIT) */ sar_direction_struct camera_cockpit_dir; /* Direction from object to camera (when * camera_ref=SAR_CAMERA_REF_SPOT) */ sar_direction_struct camera_spot_dir; float camera_spot_dist; /* Distance from hoist to camera (when * camera_ref=SAR_CAMERA_REF_HOIST) */ sar_direction_struct camera_hoist_dir; float camera_hoist_dist; /* Position of camera (when camera_ref=SAR_CAMERA_REF_MAP) */ sar_position_struct camera_map_pos; /* Position of camera (when camera_ref=SAR_CAMERA_REF_TOWER) */ sar_position_struct camera_tower_pos; /* Target object that the camera is tracking (can be -1) */ int camera_target; /* Stack of camera rotation matrixes (set in sardraw.c) to * rotate any vertex relative to the camera's rotation, each * a 3 * 3 matrix. * Member camera_rotmatrix_count indicates the actual number * of matrixes set, which is equal or less than * SAR_CAMERA_ROTMATRIX_MAX */ #define SAR_CAMERA_ROTMATRIX_MAX 5 double camera_rotmatrix[SAR_CAMERA_ROTMATRIX_MAX][3 * 3]; int camera_rotmatrix_count; /* Ear position, this is updated when the scene is drawn and * the camera set */ sar_position_struct ear_pos; /* Global Primary Light */ /* Position offset * This specifies a unit vector that is to be applied to the * camera's position to position the Global Primary Light */ sar_position_struct light_pos; /* Intensity/color * This is not the color of the sun, the sun color is found in * sun_low_color and sun_high_color */ sar_color_struct light_color; char light_visibility_hint; /* 1 if above horizon */ /* Light position coefficient orthogonal to camera's center, * the range is from [-1.0 to 1.0] (values out of this range * mean that it is out of the camera's view */ float light_xc, light_yc; /* Ground Base */ sar_scene_base_struct base; /* Horizon */ sar_scene_horizon_struct horizon; /* Cloud Layers */ sar_cloud_layer_struct **cloud_layer; int total_cloud_layers; /* Cloud Billboards */ sar_cloud_bb_struct **cloud_bb; int total_cloud_bbs; /* Primary Lightening Coeff (0.0 to 1.0, 0.0=off), this is * set to positive when the cloud billboard's lightening is * active, updated in SARSimUpdateScene() */ float pri_lightening_coeff; /* Loaded Textures List */ v3d_texture_ref_struct **texture_ref; int total_texture_refs; /* Index references to specific textures (a value can be -1 if * the texture in question was not loaded in the texture_ref * list) */ int texnum_sun, texnum_moon, texnum_spotlightcast; /* Global Sound Sources */ sar_sound_source_struct **sndsrc; int total_sndsrcs; /* Player control panel (ControlPanel *) */ void *player_control_panel; /* Messages list */ char **message; int total_messages; /* Display message until this time runs out (in milliseconds), * a value of 0 milliseconds implies that the message is not to * be shown */ time_t message_display_until; /* Sticky banner message, for displaying crash reason or * mission failed reason, whenever it is not NULL */ char **sticky_banner_message; int total_sticky_banner_messages; /* Camera reference title, the name of the target object and/or * description of what the camera is showing */ char *camera_ref_title; time_t camera_ref_title_display_until; /* Flight dynamics model realm structure, used by the SFM * library as global reference while simulating all flight * dynamics models */ SFMRealmStruct *realm; } sar_scene_struct; #define SAR_SCENE(p) ((sar_scene_struct *)(p)) #define SAR_IS_CAMERA_IN_COCKPIT(s) (((s) != NULL) ? \ ((s)->camera_ref == SAR_CAMERA_REF_COCKPIT) : 0 \ ) #define SAR_IS_EAR_IN_COCKPIT(s) (((s) != NULL) ? \ ((s)->camera_ref == SAR_CAMERA_REF_COCKPIT) : 0 \ ) #endif /* OBJ_H */ searchandrescue_1.5.0/sar/v3dfio.h0000644000175000017500000000174210104532752016075 0ustar jessejesse/* V3D Format File IO */ #ifndef V3DFIO_H #define V3DFIO_H #include #include #include "v3dmp.h" #include "v3dmodel.h" #include "v3dtex.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #ifndef V3D_COMMENT_CHAR # define V3D_COMMENT_CHAR '#' #endif #ifndef V3D_SAVE_FILE_OPTIMIZATION_MAX # define V3D_SAVE_FILE_OPTIMIZATION_MAX 2 #endif extern int V3DLoadModel( const char **buf, FILE *fp, void ***mh_item, int *total_mh_items, v3d_model_struct ***model, int *total_models, void *client_data, int (*progress_cb)(void *, int, int) ); extern int V3DSaveModel( char ***buf, FILE *fp, void **mh_item, int total_mh_items, v3d_model_struct **model, int total_models, int optimization_level, /* 0 to V3D_SAVE_FILE_OPTIMIZATION_MAX. */ int strip_extras, /* 1 for true, strips extranous data. */ void *client_data, int (*progress_cb)(void *, int, int) ); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* V3DFIO_H */ searchandrescue_1.5.0/sar/human.h0000644000175000017500000000317410104532747016020 0ustar jessejesse/* Human Preset Data */ #ifndef HUMAN_H #define HUMAN_H #include #include "obj.h" /* For SAR_HUMAN_COLOR_* definations */ /* * Human Presets Data Entry: */ typedef struct { char *name; /* Weight in kg */ float mass; /* Height in meters */ float height; /* Color palette */ sar_color_struct color[SAR_HUMAN_COLORS_MAX]; /* Number of assisting humans (0 for none) */ int assisting_humans; /* Assisting human color palette */ sar_color_struct assisting_human_color[SAR_HUMAN_COLORS_MAX]; } sar_human_data_entry_struct; #define SAR_HUMAN_DATA_ENTRY(p) ((sar_human_data_entry_struct *)(p)) /* * Human Data Presets: */ typedef struct { void *core_ptr; sar_human_data_entry_struct **preset; int total_presets; } sar_human_data_struct; #define SAR_HUMAN_DATA(p) ((sar_human_data_struct *)(p)) /* In human.c */ extern sar_human_data_entry_struct *SARHumanMatchEntryByName( sar_human_data_struct *hd, const char *name ); extern sar_human_data_struct *SARHumanPresetsInit(void *core_ptr); extern void SARHumanPresetsShutdown(sar_human_data_struct *hd); extern void SARHumanEntryDelete( sar_human_data_struct *hd, sar_human_data_entry_struct *entry ); extern int SARHumanCreate( sar_human_data_struct *hd, sar_scene_struct *scene, sar_object_struct ***object, int *total_objects, sar_obj_flags_t human_flags, const char *name ); extern void SARHumanSetObjectPreset( sar_human_data_struct *hd, sar_object_struct *obj_ptr, const char *name ); /* In humanio.c */ extern int SARHumanLoadFromFile( sar_human_data_struct *w, const char *filename ); #endif /* HUMAN_H */ searchandrescue_1.5.0/sar/cmd.c0000644000175000017500000000534310104532746015445 0ustar jessejesse#include #include #include "../include/string.h" #include "gw.h" #include "messages.h" #include "cmd.h" #include "sar.h" #include "config.h" /* * Command Reference: */ typedef struct _cmd_ref_struct cmd_ref_struct; struct _cmd_ref_struct { char *name; void (*func)(SAR_CMD_PROTOTYPE); void *reserved1; void *reserved2; }; void SARCmdTextInputCB(const char *value, void *data); #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) ? strlen(s) : 0) #define STRISEMPTY(s) (((s) != NULL) ? (*(s) == '\0') : 1) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) /* * Command text input prompt callback. * * For executing a command via the text input prompt. This will * parse the command value and call the appropriate SARCmd*() * function. */ void SARCmdTextInputCB(const char *value, void *data) { char *s; const char *arg; Boolean matched_command = False; unsigned long flags = SAR_CMD_FLAG_VERBOSE | SAR_CMD_FLAG_ISUSER; char cmd[SAR_CMD_MAX]; const cmd_ref_struct *cmd_list_ptr, cmd_list[] = SAR_CMD_FUNC_REF_LIST; void (*cmd_func)(SAR_CMD_PROTOTYPE); sar_core_struct *core_ptr = SAR_CORE(data); if((value == NULL) || (core_ptr == NULL)) return; /* Parse command and value */ /* Get command */ strncpy(cmd, value, sizeof(cmd)); cmd[sizeof(cmd) - 1] = '\0'; s = strchr(cmd, ' '); if(s == NULL) s = strchr(cmd, '\t'); if(s != NULL) *s = '\0'; /* Get argument */ arg = strchr(value, ' '); if(arg == NULL) { arg = ""; } else { while(ISBLANK(*arg)) arg++; } /* Iterate through list of SARCmd*() functions to see which * command matches the command tagent from the value string */ for(cmd_list_ptr = cmd_list; cmd_list_ptr->name != NULL; cmd_list_ptr++ ) { const char *cmd_name = cmd_list_ptr->name; cmd_func = cmd_list_ptr->func; if(STRISEMPTY(cmd_name) || (cmd_func == NULL)) break; /* Commands match? */ if(!strcasecmp(cmd_name, cmd)) { /* Call the function */ cmd_func(core_ptr, arg, flags); matched_command = True; break; } } /* Did not match command? */ if(!matched_command) { if(SAR_CMD_IS_VERBOSE(flags)) { char *s = (char *)malloc( (80 + STRLEN(cmd)) * sizeof(char) ); sprintf( s, "%s: No such command.", cmd ); SARMessageAdd(core_ptr->scene, s); free(s); } } } searchandrescue_1.5.0/sar/gww.rc0000644000175000017500000000453610104532746015673 0ustar jessejesse//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. GWW_ICON_ALT_TAB ICON DISCARDABLE "gwdata\\alt_tab.ico" GWW_ICON_TITLE_BAR ICON DISCARDABLE "gwdata\\title_bar.ico" SAR_ICON2 ICON DISCARDABLE "icons\\SearchAndRescue2.ico" SAR_ICON3 ICON DISCARDABLE "icons\\SearchAndRescue3.ico" GWW_ICON_JOYSTICK ICON DISCARDABLE "gwdata\\joystick.ico" GWW_ICON_SOUND ICON DISCARDABLE "gwdata\\sound.ico" GWW_ICON_CONFIG ICON DISCARDABLE "gwdata\\config.ico" SAR_ICON4 ICON DISCARDABLE "icons\\SearchAndRescue4.ico" SAR_ICON ICON DISCARDABLE "icons\\SearchAndRescue.ico" SAR_ICON5 ICON DISCARDABLE "icons\\SearchAndRescue5.ico" #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED searchandrescue_1.5.0/sar/sardrawselect.c0000644000175000017500000001630210104532750017535 0ustar jessejesse#include #include #ifdef __MSW__ # include #endif #include #include "obj.h" #include "sar.h" #include "sardraw.h" #include "sardrawselect.h" #include "config.h" void SARDrawMapProcessHits( sar_core_struct *core_ptr, GLint hits, GLuint buffer[] ); int SARDrawMapObjNameListAppend( sar_drawmap_objname_struct ***ptr, int *total, GLuint gl_name, const char *obj_name ); void SARDrawMapObjNameListDelete( sar_drawmap_objname_struct ***ptr, int *total ); int *SARGetGCCHitList( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, int obj_num, int *hits ); 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 ); #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 STRISEMPTY(s) (((s) != NULL) ? (*(s) == '\0') : TRUE) #define RADTODEG(r) ((r) * 180 / PI) #define DEGTORAD(d) ((d) * PI / 180) /* * Called by SARDrawMap() to process the hits after drawing the * map in GL_SELECT render mode. * * Hits will be recorded on specified core's draw map object names * list. * * Inputs assumed valid. */ void SARDrawMapProcessHits( sar_core_struct *core_ptr, GLint hits, GLuint buffer[] ) { int i, j; GLuint gl_name, names, *ptr = buffer; /* Iterate through each hit */ for(i = 0; i < hits; i++) { names = *ptr; /* Number of names on this hit */ ptr += 3; /* Seek to start of names on this hit */ /* Iterate through each name on this hit */ for(j = 0; j < (int)names; j++) { /* Get the GL name which is the object's index number */ gl_name = *ptr++; /* Append this object to the names list */ SARDrawMapObjNameListAppend( &core_ptr->drawmap_objname, &core_ptr->total_drawmap_objnames, gl_name, /* Object's index */ NULL /* No object names for now */ ); } } } /* * Appends an Object Name to the Object Names List. * * Returns the index of the new Object Name or negative on error. */ int SARDrawMapObjNameListAppend( sar_drawmap_objname_struct ***ptr, int *total, GLuint gl_name, const char *obj_name ) { int n; sar_drawmap_objname_struct *name; if((ptr == NULL) || (total == NULL)) return(-2); /* Increase allocation of the Object Names List */ n = MAX(*total, 0); *total = n + 1; *ptr = (sar_drawmap_objname_struct **)realloc( *ptr, (*total) * sizeof(sar_drawmap_objname_struct *) ); if(*ptr == NULL) { *total = 0; return(-3); } /* Allocate a new Object Name */ (*ptr)[n] = name = (sar_drawmap_objname_struct *)calloc( 1, sizeof(sar_drawmap_objname_struct) ); if(name == NULL) return(-3); name->gl_name = gl_name; /* Object's index */ name->obj_name = STRDUP(obj_name); return(n); } /* * Deletes the Object Names List. */ void SARDrawMapObjNameListDelete( sar_drawmap_objname_struct ***ptr, int *total ) { int i; sar_drawmap_objname_struct *name; if((ptr == NULL) || (total == NULL)) return; for(i = 0; i < *total; i++) { name = (*ptr)[i]; if(name == NULL) continue; free(name->obj_name); free(name); } free(*ptr); *ptr = NULL; *total = 0; } /* * Draws the map in GL_SELECT render mode and processes the hits, * storing the hits on the specified core's Object Names List. * * Note: Special numbers have the base offset of (*total) added * to them. So any index that is a special number is: * * special_index = i - (*total). * * The specified obj_num (or -1 for the player object) will be * excluded from the returned index list. * * Returns a list of object indices that were hit, the calling * function must delete the returned list. */ int *SARGetGCCHitList( sar_core_struct *core_ptr, sar_scene_struct *scene, sar_object_struct ***ptr, int *total, int obj_num, int *hits ) { int i, n, hit_obj_num, *list = NULL; sar_drawmap_objname_struct *name; if(hits != NULL) *hits = 0; if((core_ptr == NULL) || (scene == NULL) || (ptr == NULL) || (total == NULL) ) return(list); /* Draw the map with draw_for_gcc set to True, this will draw * the map with an isolated camera angle looking directly * downward with respect to the specified object (or -1 for the * player object) * * The core's Object Names List will be cleared and updated * with the hits list */ SARDrawMap(core_ptr, True, False, obj_num); /* Get hits list */ for(i = 0; i < core_ptr->total_drawmap_objnames; i++) { name = core_ptr->drawmap_objname[i]; if(name == NULL) continue; /* Get the hit object number as the gl name * * Note that the hit object number may be >= to * total_objects in which case it has special meaning */ hit_obj_num = (int)name->gl_name; /* Skip if the hit object number is the same as given * object number */ if(hit_obj_num == obj_num) continue; /* Allocate more hits and append this hit object number to * the list */ if(hits != NULL) { n = MAX(*hits, 0); *hits = n + 1; list = (int *)realloc( list, (*hits) * sizeof(int) ); if(list == NULL) { *hits = 0; break; } else { list[n] = hit_obj_num; } } } return(list); } /* * Checks for ground hit contact, relative to the given obj_num. * * Checks if there is any object directly under obj_num that is * drawn. If nothing is drawn directly under the object then * got_hit will be set to False, otherwise True. * * If the scene's base type is water, then over_water will be set * True if (and only if) got_hit is False. * * Returns 0 on success or non-zero on error. */ 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 ) { if(got_hit != NULL) *got_hit = False; if(over_water != NULL) *over_water = False; if((core_ptr == NULL) || (scene == NULL) || (ptr == NULL) || (total == NULL) ) return(-1); /* Draw the map with draw_for_ghc set to True, this will draw * the map with an isolated camera angle looking directly * downward with respect to the specified object (or -1 for the * player object) * * The core's drawmap_ghc_result will be updated */ SARDrawMap(core_ptr, False, True, obj_num); /* Got hit? */ if(core_ptr->drawmap_ghc_result >= 0.5f) { /* Mark that we got a hit */ if(got_hit != NULL) *got_hit = True; /* Mark that the specified object is not over water */ if(over_water != NULL) *over_water = False; } else { /* Mark that we did not get a hit */ if(got_hit != NULL) *got_hit = False; /* Scene's base is water? */ if(scene->base_flags & SAR_SCENE_BASE_FLAG_IS_WATER) { if(over_water != NULL) *over_water = True; } else { if(over_water != NULL) *over_water = False; } } return(0); } searchandrescue_1.5.0/sar/sarcamp.h0000644000175000017500000000705011351226776016342 0ustar jessejesse/* This head 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_SEARCH 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.5.0/sar/objiopremodeled.c0000644000175000017500000003246210104532747020050 0ustar jessejesse#include #include #include #include #include "../include/string.h" #include "sfm.h" #include "v3dtex.h" #include "sarreality.h" #include "objutils.h" #include "obj.h" #include "objio.h" #include "sar.h" static void SARObjPremodeledPowerTransmissionTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ); static void SARObjPremodeledRadioTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ); static void SARObjPremodeledTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ); static void SARObjPremodeledControlTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ); static void SARObjPremodeledBuildingNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ); int SARObjPremodeledNew( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *type_name, int argc, char **argv ); #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))) /* * Creates a new Power Transmission Tower. */ static void SARObjPremodeledPowerTransmissionTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ) { int flashing; float z; int i, hazard_lights; sar_light_struct *light; /* Format: * * */ premodeled->type = SAR_OBJ_PREMODELED_POWER_TRANSMISSION_TOWER; /* Range*/ i = 0; obj_ptr->range = (float)((i < argc) ? ATOF(argv[i]) : 1000.0); /* Height (in feet)*/ i = 1; premodeled->height = (float)SFMFeetToMeters( (i < argc) ? ATOF(argv[i]) : 80.0 ); /* Number of hazard lights? */ i = 2; hazard_lights = (i < argc) ? ATOI(argv[i]) : 0; flashing = 1; z = premodeled->height; for(i = 0; i < hazard_lights; i++) { light = SARObjLightNew( scene, &obj_ptr->light, &obj_ptr->total_lights ); if(light != NULL) { if(flashing) { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->flags |= SAR_LIGHT_FLAG_STROBE; light->int_on = 800; light->int_off = 1700; } else { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->int_on = 0; light->int_off = 0; } } /* Toggle flashing, this is to create alternating steady * state and flashing hazard lights. */ flashing = !flashing; /* Decrease height*/ z -= (premodeled->height / hazard_lights); } /* Set cylendrical contact bounds, the radius of the contact * bounds is 0.3 times the height, since the height controls * a uniformed scaling the the unit width is 0.3. */ SARObjAddContactBoundsCylendrical( obj_ptr, SAR_CRASH_FLAG_CRASH_CAUSE, SAR_CRASH_TYPE_OBSTRUCTION, (float)(0.3 * premodeled->height), /* Radius*/ 0.0f, premodeled->height /* Height min and max*/ ); } /* * Creates a new Radio Tower. */ static void SARObjPremodeledRadioTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ) { int flashing; float z; int i, hazard_lights; sar_light_struct *light; /* Format: * * */ premodeled->type = SAR_OBJ_PREMODELED_RADIO_TOWER; /* Range */ i = 0; obj_ptr->range = (float)((i < argc) ? ATOF(argv[i]) : 1000.0); /* Height (in feet) */ i = 1; premodeled->height = (float)SFMFeetToMeters( (i < argc) ? ATOF(argv[i]) : 80.0 ); /* Number of hazard lights? */ i = 2; hazard_lights = (i < argc) ? ATOI(argv[i]) : 0; flashing = 1; z = premodeled->height; for(i = 0; i < hazard_lights; i++) { light = SARObjLightNew( scene, &obj_ptr->light, &obj_ptr->total_lights ); if(light != NULL) { if(flashing) { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->flags |= SAR_LIGHT_FLAG_STROBE; light->int_on = 800; light->int_off = 1700; } else { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->int_on = 0; light->int_off = 0; } } /* Toggle flashing, this is to create alternating steady * state and flashing hazard lights. */ flashing = !flashing; /* Decrease height*/ z -= (premodeled->height / hazard_lights); } /* Set cylendrical contact bounds, the radius of the contact * bounds is 0.3 times the height, since the height controls * a uniformed scaling the the unit width is 0.3. */ SARObjAddContactBoundsCylendrical( obj_ptr, SAR_CRASH_FLAG_CRASH_CAUSE, SAR_CRASH_TYPE_OBSTRUCTION, 5.0, /* Fixed radius*/ 0.0, premodeled->height /* Height min and max*/ ); } /* * Creates a new Tower. */ static void SARObjPremodeledTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ) { int flashing; float z; int i, hazard_lights; sar_light_struct *light; /* Format: * * */ premodeled->type = SAR_OBJ_PREMODELED_TOWER; /* Range*/ i = 0; obj_ptr->range = (float)((i < argc) ? ATOF(argv[i]) : 1000.0); /* Height (in feet)*/ i = 1; premodeled->height = (float)SFMFeetToMeters( (i < argc) ? ATOF(argv[i]) : 80.0 ); /* Number of hazard lights? */ i = 2; hazard_lights = (i < argc) ? ATOI(argv[i]) : 0; flashing = 1; z = premodeled->height; for(i = 0; i < hazard_lights; i++) { light = SARObjLightNew( scene, &obj_ptr->light, &obj_ptr->total_lights ); if(light != NULL) { if(flashing) { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->flags |= SAR_LIGHT_FLAG_STROBE; light->int_on = 800; light->int_off = 1700; } else { light->pos.x = 0.0f; light->pos.y = 0.0f; light->pos.z = z; light->color.r = 1.0f; light->color.g = 0.0f; light->color.b = 0.0f; light->color.a = 1.0f; light->radius = 2; light->flags |= SAR_LIGHT_FLAG_ON; light->int_on = 0; light->int_off = 0; } } /* Toggle flashing, this is to create alternating steady * state and flashing hazard lights. */ flashing = !flashing; /* Decrease height*/ z -= (premodeled->height / hazard_lights); } /* Set cylendrical contact bounds, the radius of the contact * bounds is 0.3 times the height, since the height controls * a uniformed scaling the the unit width is 0.3. */ SARObjAddContactBoundsCylendrical( obj_ptr, SAR_CRASH_FLAG_CRASH_CAUSE, SAR_CRASH_TYPE_OBSTRUCTION, 5.0, /* Fixed radius*/ 0.0, premodeled->height /* Height min and max*/ ); } /* * Creates a new Control Tower. */ static void SARObjPremodeledControlTowerNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ) { int i, n; /* Format: * * */ premodeled->type = SAR_OBJ_PREMODELED_CONTROL_TOWER; /* Range*/ i = 0; obj_ptr->range = (float)((i < argc) ? ATOF(argv[i]) : 1000.0); /* Length*/ i = 1; premodeled->length = (float)((i < argc) ? ATOF(argv[i]) : 15.0); /* Width*/ i = 2; premodeled->width = (float)((i < argc) ? ATOF(argv[i]) : 15.0); /* Height (in feet)*/ i = 3; premodeled->height = (float)SFMFeetToMeters( (i < argc) ? ATOF(argv[i]) : 80.0 ); /* Walls texture*/ i = 4; if(i < argc) { n = 0; if(n < SAR_OBJ_PREMODEL_MAX_TEXTURES) premodeled->tex_num[n] = SARGetTextureRefNumberByName( scene, argv[i] ); } /* Roof texture*/ i = 5; if(i < argc) { n = 1; if(n < SAR_OBJ_PREMODEL_MAX_TEXTURES) premodeled->tex_num[n] = SARGetTextureRefNumberByName( scene, argv[i] ); } /* Set contact bounds*/ SARObjAddContactBoundsRectangular( obj_ptr, SAR_CRASH_FLAG_CRASH_CAUSE | SAR_CRASH_FLAG_SUPPORT_SURFACE, SAR_CRASH_TYPE_BUILDING, -(premodeled->length / 2), (premodeled->length / 2), -(premodeled->width / 2), (premodeled->width / 2), 0.0, premodeled->height ); } /* * Creates a new Building. */ static void SARObjPremodeledBuildingNew( sar_core_struct *core_ptr, sar_scene_struct *scene, int obj_num, sar_object_struct *obj_ptr, sar_object_premodeled_struct *premodeled, int argc, char **argv ) { int i, n; /* Format: * * * */ premodeled->type = SAR_OBJ_PREMODELED_BUILDING; /* Range*/ i = 0; obj_ptr->range = (float)((i < argc) ? ATOF(argv[i]) : 1000.0); /* Length*/ i = 1; premodeled->length = (float)((i < argc) ? ATOF(argv[i]) : 50.0); /* Width*/ i = 2; premodeled->width = (float)((i < argc) ? ATOF(argv[i]) : 20.0); /* Height (in feet)*/ i = 3; premodeled->height = (float)SFMFeetToMeters( (i < argc) ? ATOF(argv[i]) : 50.0 ); /* Walls texture*/ i = 4; n = 0; if(i < argc) { if(n < SAR_OBJ_PREMODEL_MAX_TEXTURES) premodeled->tex_num[n] = SARGetTextureRefNumberByName( scene, argv[i] ); } /* Walls night*/ i = 5; n = 1; if(i < argc) { if(n < SAR_OBJ_PREMODEL_MAX_TEXTURES) premodeled->tex_num[n] = SARGetTextureRefNumberByName( scene, argv[i] ); } /* Roof texture*/ i = 6; n = 2; if(i < argc) { if(n < SAR_OBJ_PREMODEL_MAX_TEXTURES) premodeled->tex_num[n] = SARGetTextureRefNumberByName( scene, argv[i] ); } /* Set contact bounds*/ SARObjAddContactBoundsRectangular( obj_ptr, SAR_CRASH_FLAG_CRASH_CAUSE | SAR_CRASH_FLAG_SUPPORT_SURFACE, SAR_CRASH_TYPE_BUILDING, -(premodeled->length / 2), (premodeled->length / 2), -(premodeled->width / 2), (premodeled->width / 2), 0.0, premodeled->height ); } /* * Creates a new Permodeled Object. */ int SARObjPremodeledNew( sar_core_struct *core_ptr, sar_scene_struct *scene, const char *type_name, int argc, char **argv ) { int obj_num; sar_object_struct *obj_ptr; sar_object_premodeled_struct *premodeled; if((scene == NULL) || (type_name == NULL)) return(-1); /* Create new premodeled object */ obj_num = SARObjNew( scene, &core_ptr->object, &core_ptr->total_objects, SAR_OBJ_TYPE_PREMODELED ); obj_ptr = (obj_num > -1) ? core_ptr->object[obj_num] : NULL; if(obj_ptr == NULL) return(-1); /* Get pointer to premodeled object data substructure*/ premodeled = SAR_OBJ_GET_PREMODELED(obj_ptr); /* Handle by preset model type name */ /* Standard building */ if(!strcasecmp(type_name, "building")) { SARObjPremodeledBuildingNew( core_ptr, scene, obj_num, obj_ptr, premodeled, argc, argv ); } /* Control tower */ else if(!strcasecmp(type_name, "control_tower")) { SARObjPremodeledControlTowerNew( core_ptr, scene, obj_num, obj_ptr, premodeled, argc, argv ); } /* Tower */ else if(!strcasecmp(type_name, "tower")) { SARObjPremodeledTowerNew( core_ptr, scene, obj_num, obj_ptr, premodeled, argc, argv ); } /* Radio tower */ else if(!strcasecmp(type_name, "radio_tower")) { SARObjPremodeledRadioTowerNew( core_ptr, scene, obj_num, obj_ptr, premodeled, argc, argv ); } /* Power transmission tower */ else if(!strcasecmp(type_name, "power_transmission_tower")) { SARObjPremodeledPowerTransmissionTowerNew( core_ptr, scene, obj_num, obj_ptr, premodeled, argc, argv ); } else { fprintf( stderr, "SARObjPremodeledNew(): Unsupported preset model type name `%s'.\n", type_name ); } return(obj_num); } searchandrescue_1.5.0/sar/horizon.c0000644000175000017500000000673410104532746016377 0ustar jessejesse#include #include #include "v3dtex.h" #include "obj.h" #include "horizon.h" v3d_texture_ref_struct *SARCreateHorizonTexture( const char *name, const sar_color_struct *start_color, /* Top color */ const sar_color_struct *end_color, /* Bottom color */ int height, /* Width in pixels */ float midpoint ); #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) ? strlen(s) : 0) #define STRISEMPTY(s) (((s) != NULL) ? (*(s) == '\0') : 1) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) /* * Returns a 1D gradient horizon texture generated by the * given colors. */ v3d_texture_ref_struct *SARCreateHorizonTexture( const char *name, const sar_color_struct *start_color, /* Top color */ const sar_color_struct *end_color, /* Bottom color */ int height, /* Width in pixels */ float midpoint ) { int y, y_midpoint; float dr, dg, db; int bits_per_pixel = 32; u_int8_t *data; v3d_texture_ref_struct *t; u_int8_t r, g, b; u_int8_t *ptr8; if((start_color == NULL) || (end_color == NULL) || (height <= 0) ) return(NULL); /* Allocate tempory image data that will be rendered and used * to create the texture * * Note that we are allocating more bytes since the data passed * for creation is only 24 bits (3 bytes) */ data = (u_int8_t *)malloc( height * (bits_per_pixel >> 3) ); /* Render the image */ y_midpoint = (int)MIN(midpoint * height, height - 1); dr = end_color->r - start_color->r; /* Color delta coeffs */ dg = end_color->g - start_color->g; db = end_color->b - start_color->b; switch(bits_per_pixel) { case 32: ptr8 = (u_int8_t *)(&data[0]); for(y = 0; y < height; y++) { if(y < y_midpoint) { float coeff = (float)((y_midpoint > 0) ? (float)y / (float)y_midpoint : 0.0 ); r = (u_int8_t)CLIP( (start_color->r + (dr / 2 * coeff)) * 0xff, 0x00, 0xff ); g = (u_int8_t)CLIP( (start_color->g + (dg / 2 * coeff)) * 0xff, 0x00, 0xff ); b = (u_int8_t)CLIP( (start_color->b + (db / 2 * coeff)) * 0xff, 0x00, 0xff ); } else { float coeff = (float)(((height - y_midpoint) > 0) ? (float)(y - y_midpoint) / (float)(height - y_midpoint) : 1.0 ); r = (u_int8_t)CLIP( (start_color->r + (dr / 2) + (dr / 2 * coeff)) * 0xff, 0x00, 0xff ); g = (u_int8_t)CLIP( (start_color->g + (dg / 2) + (dg / 2 * coeff)) * 0xff, 0x00, 0xff ); b = (u_int8_t)CLIP( (start_color->b + (db / 2) + (db / 2 * coeff)) * 0xff, 0x00, 0xff ); } *ptr8++ = r; *ptr8++ = g; *ptr8++ = b; } break; } /* Create texture from image data */ t = V3DTextureLoadFromData1D( data, name, height, bits_per_pixel, V3D_TEX_FORMAT_RGB, NULL, NULL ); V3DTexturePriority(t, 0.98f); /* Delete the tempory image data */ free(data); return(t); } searchandrescue_1.5.0/sar/cpinsbearing.h0000644000175000017500000000171010104532746017345 0ustar jessejesse/* Control Panel Instrument - Bearing */ #ifndef CPINSBEARING_H #define CPINSBEARING_H #include #include #include "v3dtex.h" #include "cpvalues.h" #include "cpins.h" /* * This instrument type code: */ #define CPINS_TYPE_BEARING 15 /* * Bearing Instrument structure: */ typedef struct _CPInsBearing CPInsBearing; struct _CPInsBearing { CPIns ins; /* Last megnetic bearing in radians. */ float bearing_mag_last; /* Current megnetic bearing change velocity in radians per * second. */ float bearing_mag_vel; /* Megnetic bearing change velocity decrease in radians per * second (must be positive). */ float bearing_mag_vel_dec; /* Current mechanical bearing offset in delta radians. */ float bearing_mechanical_offset; }; #define CPINS_BEARING(p) ((CPInsBearing *)(p)) #define CPINS_IS_BEARING(p) (CPINS_TYPE(p) == CPINS_TYPE_BEARING) extern CPIns *CPInsBearingNew(void *cp); #endif /* CPINSBEARING_H */ searchandrescue_1.5.0/sar/missionio.c0000644000175000017500000017555210104532747016726 0ustar jessejesse#include #include #include #include #include #include #include #include "../include/fio.h" #include "../include/string.h" #include "../include/strexp.h" #include "../include/disk.h" #include "sfm.h" #include "obj.h" #include "objutils.h" #include "objio.h" #include "menu.h" #include "sarreality.h" #include "weather.h" #include "mission.h" #include "simutils.h" #include "sar.h" #include "sarfio.h" #include "sceneio.h" #include "missionio.h" #include "config.h" static int SARMissionGetInterceptNameFromScene( const char *filename, const char *obj_name, sar_intercept_struct *intercept ); static int SARMissionLoadSceneMapToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_map_struct *map_ptr, const char *filename /* Scene file */ ); static int SARMissionLoadSceneMapToMenuMapMarkings( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_map_struct *map_ptr, const char *scene_filename, const char *mission_filename ); char *SARMissionLoadDescription(const char *filename); void SARMissionLoadSceneToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, const char *filename /* Mission file name */ ); void SARMissionLoadMissionLogToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, const char *filename /* Mission log file name */ ); sar_mission_struct *SARMissionLoadFromFile( sar_core_struct *core_ptr, const char *filename, void *client_data, int (*progress_func)(void *, long, long) ); void SARMissionLogReset( sar_core_struct *core_ptr, sar_mission_struct *mission, const char *filename /* Mission log file name */ ); void SARMissionLogEvent( sar_core_struct *core_ptr, sar_mission_struct *mission, int event_type, /* One of SAR_LOG_EVENT_* */ float tod, /* Time of day in seconds since midnight */ sar_position_struct *pos, /* Position of event */ const float *value, /* Additional values */ int total_values, /* Total number of additional values */ const char *message, /* The message */ const char *filename /* Mission log file name */ ); #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 STRISEMPTY(s) (((s) != NULL) ? (*(s) == '\0') : 1) #define RADTODEG(r) ((r) * 180.0 / PI) #define DEGTORAD(d) ((d) * PI / 180.0) #define ISCOMMENT(c) ((c) == SAR_COMMENT_CHAR) #define ISCR(c) (((c) == '\n') || ((c) == '\r')) /* * Load intercept by name from scene file, returns 0 on success * or -1 on no match. */ static int SARMissionGetInterceptNameFromScene( const char *filename, const char *obj_name, sar_intercept_struct *intercept ) { int i, status, ptype, total_parms; char *cur_obj_name = NULL; void *p, **parm; sar_parm_version_struct *p_version; sar_parm_object_name_struct *p_object_name; sar_parm_translate_struct *p_translate; sar_parm_rotate_struct *p_rotate; Boolean matched_translate = False, matched_rotate = False; if(STRISEMPTY(filename) || STRISEMPTY(obj_name) || (intercept == NULL) ) return(-1); /* Load parms from scene file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_SCENE, &parm, &total_parms, -1, NULL, NULL ); if(status) return(-1); /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", filename, p_version->major, p_version->minor, p_version->release, PROG_VERSION_MAJOR, PROG_VERSION_MINOR, PROG_VERSION_RELEASE ); } break; case SAR_PARM_OBJECT_NAME: p_object_name = (sar_parm_object_name_struct *)p; /* Update current object name */ free(cur_obj_name); cur_obj_name = STRDUP(p_object_name->name); /* Reset all other context values */ matched_translate = False; matched_rotate = False; break; case SAR_PARM_TRANSLATE: p_translate = (sar_parm_translate_struct *)p; if((cur_obj_name != NULL) && !matched_translate) { if(!strcasecmp(cur_obj_name, obj_name)) { intercept->x = p_translate->translate.x; intercept->y = p_translate->translate.y; intercept->z = p_translate->translate.z; intercept->radius = 40; /* Explicitly set */ matched_translate = True; } } break; case SAR_PARM_ROTATE: p_rotate = (sar_parm_rotate_struct *)p; if((cur_obj_name != NULL) && !matched_rotate) { if(!strcasecmp(cur_obj_name, obj_name)) { /* TODO, not really needed right now */ matched_rotate = True; } } break; } } /* Delete all loaded parms */ SARParmDeleteAll(&parm, &total_parms); free(cur_obj_name); return(0); } /* * Loads the scene map of the given scene specified by filename * to the given map object as a texture. Any existing texture already * loaded on the given map object will be unloaded first. * * Returns -1 on error or 0 on success. * * This function is intended to be called by * SARMissionLoadMissionLogToMenuMap(). */ static int SARMissionLoadSceneMapToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_map_struct *map_ptr, const char *filename /* Scene file */ ) { int i, status, ptype, total_parms; const char *img_path; void *p, **parm; sar_parm_version_struct *p_version; sar_parm_name_struct *p_name; sar_parm_scene_map_struct *p_scene_map; if(STRISEMPTY(filename) || (map_ptr == NULL)) return(-1); /* Load parms from scene file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_SCENE, &parm, &total_parms, -1, NULL, NULL ); if(status) return(-1); /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", 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(map_ptr->title); map_ptr->title = STRDUP(p_name->name); break; case SAR_PARM_SCENE_MAP: p_scene_map = (sar_parm_scene_map_struct *)p; /* Width and height in meters */ map_ptr->bg_tex_width = (float)MAX(p_scene_map->width, 10.0); map_ptr->bg_tex_height = (float)MAX(p_scene_map->height, 10.0); /* Texture image path */ img_path = p_scene_map->file; if(!STRISEMPTY(img_path)) { char *dpath; if(ISPATHABSOLUTE(img_path)) { dpath = STRDUP(img_path); } else { struct stat stat_buf; const char *s = PrefixPaths(dname.local_data, img_path); if((s != NULL) ? stat(s, &stat_buf) : True) s = PrefixPaths( dname.global_data, img_path ); dpath = STRDUP(s); } /* Unload menu map's background texture as needed */ V3DTextureDestroy(map_ptr->bg_tex); /* Load new texture for menu map's background */ map_ptr->bg_tex = V3DTextureLoadFromFile2DPreempt( dpath, "mission_map_tex", /* Not used */ V3D_TEX_FORMAT_RGB /* Destination format */ ); V3DTexturePriority(map_ptr->bg_tex, 0.95f); free(dpath); } break; } /* Handle by parm type */ } /* Iterate through loaded parms */ /* Delete all loaded parms */ SARParmDeleteAll(&parm, &total_parms); return(0); } /* * Called by SARMissionLoadSceneMapToMenuMap(). * * Loads the scene map and markings of the given scene specified by * filename to the map object as a texture * * Intercept points are not loaded. */ static int SARMissionLoadSceneMapToMenuMapMarkings( sar_core_struct *core_ptr, sar_menu_struct *m, sar_menu_map_struct *map_ptr, const char *scene_filename, const char *mission_filename ) { int i, n, pass, ptype, total_parms; const char *img_path; void *p, **parm; sar_menu_color_struct fg_color; sar_menu_map_marking_struct *marking_ptr; Boolean got_translate, got_rotate, got_object_name, got_object_map_desc; sar_parm_version_struct *p_version; sar_parm_name_struct *p_name; sar_parm_scene_map_struct *p_scene_map; 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_premodeled_struct *p_new_premodeled; sar_parm_translate_struct *p_translate; sar_parm_rotate_struct *p_rotate; sar_parm_object_name_struct *p_object_name; sar_parm_object_map_description_struct *p_object_map_desc; if((m == NULL) || (map_ptr == NULL)) return(-1); /* Load parms from scene file */ if(SARParmLoadFromFile( scene_filename, SAR_FILE_FORMAT_SCENE, &parm, &total_parms, -1, NULL, NULL )) return(-1); /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", scene_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(map_ptr->title); map_ptr->title = STRDUP(p_name->name); break; case SAR_PARM_SCENE_MAP: p_scene_map = (sar_parm_scene_map_struct *)p; /* Width and height in meters */ map_ptr->bg_tex_width = (float)MAX(p_scene_map->width, 10.0); map_ptr->bg_tex_height = (float)MAX(p_scene_map->height, 10.0); /* Texture image path */ img_path = p_scene_map->file; if(!STRISEMPTY(img_path)) { char *dpath; if(ISPATHABSOLUTE(img_path)) { dpath = STRDUP(img_path); } else { struct stat stat_buf; const char *s = PrefixPaths(dname.local_data, img_path); if((s != NULL) ? stat(s, &stat_buf) : True) s = PrefixPaths( dname.global_data, img_path ); dpath = STRDUP(s); } /* Unload menu map's background texture as needed */ V3DTextureDestroy(map_ptr->bg_tex); /* Load new texture for menu map's background */ map_ptr->bg_tex = V3DTextureLoadFromFile2DPreempt( dpath, "mission_map_tex", /* Not used */ V3D_TEX_FORMAT_RGB /* Destination format */ ); V3DTexturePriority(map_ptr->bg_tex, 0.95f); free(dpath); } break; } /* Handle by parm type */ } /* Iterate through loaded parms */ /* Resets all local contexts pointers */ #define RESET_CONTEXTS { \ marking_ptr = NULL; \ got_translate = False; \ got_rotate = False; \ got_object_name = False; \ got_object_map_desc = False; \ } /* Reset local contexts */ RESET_CONTEXTS /* Perform two iterations, the first on the existing loaded * parms and then reload the parms from the mission file * and load from them. This will ensure that we get map markings * from first the scene file and then the mission file. */ for(pass = 0; pass < 2; pass++) { /* Iterate through loaded parms (second time around) */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; switch(ptype) { case SAR_PARM_NEW_OBJECT: p_new_object = (sar_parm_new_object_struct *)p; /* Reset local contexts */ RESET_CONTEXTS /* Ignore for now */ break; case SAR_PARM_NEW_HELIPAD: p_new_helipad = (sar_parm_new_helipad_struct *)p; /* Reset local contexts */ RESET_CONTEXTS /* Set foreground color */ fg_color.a = 1.0f; fg_color.r = 0.0f; fg_color.g = 1.0f; fg_color.b = 0.0f; /* Allocate new marking on map for intercept */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, 0.0, 0.0, 0.0, 0.0, core_ptr->menumap_helipad_img, NULL ); marking_ptr = (n > -1) ? map_ptr->marking[n] : NULL; break; case SAR_PARM_NEW_RUNWAY: p_new_runway = (sar_parm_new_runway_struct *)p; /* Reset local contexts */ RESET_CONTEXTS /* Ignore for now */ break; case SAR_PARM_NEW_HUMAN: p_new_human = (sar_parm_new_human_struct *)p; /* Reset local contexts */ RESET_CONTEXTS /* Ignore for now */ break; case SAR_PARM_NEW_PREMODELED: p_new_premodeled = (sar_parm_new_premodeled_struct *)p; /* Reset local contexts */ RESET_CONTEXTS /* Ignore for now */ break; case SAR_PARM_TRANSLATE: p_translate = (sar_parm_translate_struct *)p; if((marking_ptr != NULL) && !got_translate) { marking_ptr->x = p_translate->translate.x; marking_ptr->y = p_translate->translate.y; got_translate = True; } break; case SAR_PARM_ROTATE: p_rotate = (sar_parm_rotate_struct *)p; if((marking_ptr != NULL) && !got_rotate) { /* Ignore for now */ got_rotate = True; } break; case SAR_PARM_OBJECT_NAME: p_object_name = (sar_parm_object_name_struct *)p; if((marking_ptr != NULL) && !got_object_name) { /* Ignore for now */ got_object_name = True; } break; case SAR_PARM_OBJECT_MAP_DESCRIPTION: p_object_map_desc = (sar_parm_object_map_description_struct *)p; if((marking_ptr != NULL) && !got_object_map_desc) { free(marking_ptr->desc); marking_ptr->desc = STRDUP( p_object_map_desc->description ); got_object_map_desc = True; } break; } /* Handle by parm type */ } /* Iterate through loaded parms (second time around) */ if(pass >= 1) break; /* Delete loaded parms and then load parms from mission file */ SARParmDeleteAll(&parm, &total_parms); if(SARParmLoadFromFile( mission_filename, SAR_FILE_FORMAT_MISSION, &parm, &total_parms, -1, NULL, NULL )) break; RESET_CONTEXTS } /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); #undef RESET_CONTEXTS return(0); } /* * Returns a pointer to a dynamically allocated description fetched * from the specified mission file. * * The calling function needs to deallocate the returned string. */ char *SARMissionLoadDescription(const char *filename) { int i, status, ptype, total_parms; void *p, **parm; sar_parm_description_struct *p_desc; char *desc = NULL; if(STRISEMPTY(filename)) return(desc); /* Load parms from mission file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_MISSION, &parm, &total_parms, SAR_PARM_DESCRIPTION, NULL, NULL ); if(status) return(desc); /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; ptype = *(int *)p; switch(ptype) { case SAR_PARM_DESCRIPTION: p_desc = (sar_parm_description_struct *)p; free(desc); desc = STRDUP(p_desc->description); break; } } /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); return(desc); } /* * Loads the scene specified by filename to the map object on the * menu. * * All relivent objects specified in the scene will be loaded * as markings on the map object. */ void SARMissionLoadSceneToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, const char *filename /* Mission file name */ ) { int i, n, status, ptype, total_parms; void *p, **parm; sar_parm_version_struct *p_version; sar_parm_mission_scene_file_struct *p_mission_scene_file; sar_parm_mission_begin_at_struct *p_mission_begin_at; sar_parm_mission_begin_at_pos_struct *p_mission_begin_at_pos; sar_parm_mission_arrive_at_struct *p_mission_arrive_at; sar_parm_mission_add_intercept_struct *p_mission_add_intercept; int map_num = -1; sar_menu_map_struct *map_ptr = NULL; const char *s; Boolean begin_at_set = False; char *scene_filename = NULL, *arrive_at_name = NULL, *begin_at_name = NULL; sar_menu_map_marking_struct *marking_ptr = NULL, *intercept_marking_ptr = NULL; int intercepts_set = 0; if(m == NULL) return; /* Get first map object on the menu */ for(i = 0; i < m->total_objects; i++) { p = m->object[i]; if(p == NULL) continue; ptype = (*(int *)p); if(ptype == SAR_MENU_OBJECT_TYPE_MAP) { map_num = i; map_ptr = SAR_MENU_MAP(p); break; } } if(map_ptr == NULL) return; /* Delete all markings on menu's map object */ SARMenuMapDeleteAllMarkings(map_ptr); /* If no filename was given then only delete map markings */ if(STRISEMPTY(filename)) return; /* Note that order of which parameters appear in the mission * file is important! * * We expect to parse certain parameters before others */ /* Load parms from mission file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_MISSION, &parm, &total_parms, -1, NULL, NULL ); if(status) return; /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", filename, p_version->major, p_version->minor, p_version->release, PROG_VERSION_MAJOR, PROG_VERSION_MINOR, PROG_VERSION_RELEASE ); } break; case SAR_PARM_MISSION_SCENE_FILE: p_mission_scene_file = (sar_parm_mission_scene_file_struct *)p; s = p_mission_scene_file->file; if(!STRISEMPTY(s)) { if(ISPATHABSOLUTE(s)) { free(scene_filename); scene_filename = STRDUP(s); } else { struct stat stat_buf; char *s2 = PrefixPaths(dname.local_data, s); if((s2 != NULL) ? stat(s2, &stat_buf) : True) s2 = PrefixPaths(dname.global_data, s); if(s2 != NULL) { free(scene_filename); scene_filename = STRDUP(s2); } } /* Load information from scene file which are * relivent to the mission map (such as map * background texture file and landmarks) */ SARMissionLoadSceneMapToMenuMapMarkings( core_ptr, m, map_ptr, scene_filename, /* Scene file */ filename /* Mission file */ ); } break; case SAR_PARM_MISSION_BEGIN_AT: p_mission_begin_at = (sar_parm_mission_begin_at_struct *)p; if(p_mission_begin_at->name != NULL) { sar_menu_color_struct fg_color; sar_intercept_struct intercept; memset(&intercept, 0x00, sizeof(sar_intercept_struct)); /* Update begin at name */ free(begin_at_name); begin_at_name = STRDUP(p_mission_begin_at->name); /* Match intercept by name and set begin at location (only * if the begin at location has not been set yet) */ if(!SARMissionGetInterceptNameFromScene( scene_filename, begin_at_name, &intercept ) && !begin_at_set) { fg_color.a = 1.0; fg_color.r = 0.0; fg_color.g = 1.0; fg_color.b = 0.0; /* Allocate new marking on map for intercept */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE, &fg_color, intercept.x, intercept.y, 0.0, 0.0, NULL, NULL ); marking_ptr = ((n >= 0) ? map_ptr->marking[n] : NULL); intercept_marking_ptr = marking_ptr; if(marking_ptr != NULL) { intercepts_set++; /* Reset meters to pixels coeff zoom */ map_ptr->m_to_pixels_coeff = (float)SAR_MAP_DEF_MTOP_COEFF; /* Set initial scroll position on map with * respect to the begin at location */ map_ptr->scroll_x = (int)(-intercept.x * map_ptr->m_to_pixels_coeff); map_ptr->scroll_y = (int)(-intercept.y * map_ptr->m_to_pixels_coeff); /* Reset selected_marking on menu map */ map_ptr->selected_marking = -1; } begin_at_set = True; } } break; case SAR_PARM_MISSION_BEGIN_AT_POS: p_mission_begin_at_pos = (sar_parm_mission_begin_at_pos_struct *)p; if(!begin_at_set) { sar_menu_color_struct fg_color; sar_position_struct *ipos = &p_mission_begin_at_pos->pos; fg_color.a = 1.0f; fg_color.r = 0.0f; fg_color.g = 1.0f; fg_color.b = 0.0f; /* Allocate new marking on map for intercept */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE, &fg_color, ipos->x, ipos->y, 0.0f, 0.0f, NULL, NULL ); marking_ptr = (n > -1) ? map_ptr->marking[n] : NULL; intercept_marking_ptr = marking_ptr; if(marking_ptr != NULL) { intercepts_set++; /* Reset meters to pixels coeff zoom */ map_ptr->m_to_pixels_coeff = (float)SAR_MAP_DEF_MTOP_COEFF; /* Set initial scroll position on map with * respect to the begin at location */ map_ptr->scroll_x = (int)(-ipos->x * map_ptr->m_to_pixels_coeff); map_ptr->scroll_y = (int)(-ipos->y * map_ptr->m_to_pixels_coeff); /* Reset selected_marking on menu map */ map_ptr->selected_marking = -1; } begin_at_set = True; } break; case SAR_PARM_MISSION_ARRIVE_AT: p_mission_arrive_at = (sar_parm_mission_arrive_at_struct *)p; if(p_mission_arrive_at->name) { free(arrive_at_name); arrive_at_name = STRDUP(p_mission_arrive_at->name); } break; case SAR_PARM_MISSION_ADD_INTERCEPT: p_mission_add_intercept = (sar_parm_mission_add_intercept_struct *)p; if(1) { sar_intercept_struct intercept; memset(&intercept, 0x00, sizeof(sar_intercept_struct)); /* Set intercept by reference code */ switch(p_mission_add_intercept->ref_code) { case 3: /* Arrive at location */ SARMissionGetInterceptNameFromScene( scene_filename, arrive_at_name, &intercept ); break; case 2: /* Begin at location */ SARMissionGetInterceptNameFromScene( scene_filename, begin_at_name, &intercept ); break; default: /* Standard intercept */ intercept.x = p_mission_add_intercept->pos.x; intercept.y = p_mission_add_intercept->pos.y; intercept.z = p_mission_add_intercept->pos.z; intercept.radius = p_mission_add_intercept->radius; intercept.urgency = p_mission_add_intercept->urgency; break; } /* Allocate new map marking structure, note previous * marking structure should already be allocated from * another add intercept parameter or begin at name * parameter */ if((marking_ptr != NULL) && (intercept_marking_ptr != NULL) ) { sar_menu_map_marking_struct *new_ptr; /* Allocate new intercept marking structure and * copy over end position values from previous * marking structure */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL ); new_ptr = (n > -1) ? map_ptr->marking[n] : NULL; /* Set end position on last marking structure */ marking_ptr->x_end = intercept.x; marking_ptr->y_end = intercept.y; intercepts_set++; /* New marking structure allocated successfully? */ if(new_ptr != NULL) { /* Copy over fg color from previous marking */ memcpy( &new_ptr->fg_color, &marking_ptr->fg_color, sizeof(sar_menu_color_struct) ); new_ptr->x = intercept.x; new_ptr->y = intercept.y; intercepts_set++; intercept_marking_ptr = new_ptr; marking_ptr = new_ptr; } else { intercept_marking_ptr = NULL; marking_ptr = NULL; } /* Allocate another marking structure to represent * way point icon */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, NULL, intercept.x, intercept.y, 0.0f, 0.0f, core_ptr->menumap_intercept_img, NULL ); new_ptr = ((n >= 0) ? map_ptr->marking[n] : NULL); } } break; } /* Handle parm by type */ } /* Iterate through loaded parms */ /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); /* Delete local context names */ free(scene_filename); scene_filename = NULL; free(arrive_at_name); arrive_at_name = NULL; free(begin_at_name); begin_at_name = NULL; /* If the number of intercepts set on the map is an odd number, * then that implies that the last intercept line marking is * extraneous */ if(intercepts_set & 1) { /* Delete the last marking pointer of type * SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE * * Iterate from last to first of all markings on the map */ for(i = map_ptr->total_markings - 1; i >= 0; i--) { marking_ptr = map_ptr->marking[i]; if(marking_ptr == NULL) continue; /* Check marking type */ if(marking_ptr->type == SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE) { /* Need to delete this marking on the map, set the * pointer to NULL after deleting it */ free(marking_ptr); map_ptr->marking[i] = NULL; /* Do not delete any more markings */ break; } } } } /* * Procedure to load the mission log specified by filename to the * map object on the given menu. */ void SARMissionLoadMissionLogToMenuMap( sar_core_struct *core_ptr, sar_menu_struct *m, const char *filename /* Mission log file name */ ) { int i, ptype, status, total_parms; void *p, **parm; sar_position_struct *pos; sar_parm_version_struct *p_version; sar_parm_mission_log_header_struct *p_mission_log_header; sar_parm_mission_log_event_struct *p_mission_log_event; int map_num = -1; sar_menu_map_struct *map_ptr = NULL; Boolean handled_header = False; char *title = NULL, *scene_filename = NULL, *player_stats_filename = NULL; sar_menu_map_marking_struct *last_intercept_marking = NULL; int total_intercept_markings = 0; int total_events = 0; if(m == NULL) return; /* Get first map object on the menu */ for(i = 0; i < m->total_objects; i++) { p = m->object[i]; if(p == NULL) continue; ptype = (*(int *)p); if(ptype == SAR_MENU_OBJECT_TYPE_MAP) { map_num = i; map_ptr = SAR_MENU_MAP(p); break; } } if(map_ptr == NULL) return; /* Delete all markings on menu's map object */ SARMenuMapDeleteAllMarkings(map_ptr); /* If no filename was given then only delete map markings */ if(STRISEMPTY(filename)) return; /* Load parms from mission log file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_MISSION_LOG, &parm, &total_parms, -1, NULL, NULL ); if(status) return; /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", filename, p_version->major, p_version->minor, p_version->release, PROG_VERSION_MAJOR, PROG_VERSION_MINOR, PROG_VERSION_RELEASE ); } break; case SAR_PARM_MISSION_LOG_HEADER: p_mission_log_header = (sar_parm_mission_log_header_struct *)p; free(title); title = STRDUP(p_mission_log_header->title); free(scene_filename); scene_filename = STRDUP(p_mission_log_header->scene_file); free(player_stats_filename); player_stats_filename = STRDUP(p_mission_log_header->player_stats_file); /* Handle this header if we have not yet handled the * header earlier */ if(!handled_header) { /* Got scene file name from reading the log file? */ if(scene_filename != NULL) SARMissionLoadSceneMapToMenuMap( core_ptr, m, map_ptr, scene_filename ); /* Reset map */ map_ptr->m_to_pixels_coeff = (float)SAR_MAP_DEF_MTOP_COEFF; /* Reset initial scroll position */ map_ptr->scroll_x = (int)( 0.0f * map_ptr->m_to_pixels_coeff ); map_ptr->scroll_y = (int)( 0.0f * map_ptr->m_to_pixels_coeff ); /* Reset selected_marking on menu map */ map_ptr->selected_marking = -1; /* Title needs to be set after calling * SARMissionLoadSceneMapToMenuMap() since it will * set the title */ free(map_ptr->title); map_ptr->title = STRDUP(title); /* Mark that we handled the header */ handled_header = True; } break; case SAR_PARM_MISSION_LOG_EVENT: p_mission_log_event = (sar_parm_mission_log_event_struct *)p; pos = &p_mission_log_event->pos; if(True) { int n; sar_menu_color_struct fg_color; fg_color.a = 1.0f; fg_color.r = 0.0f; fg_color.g = 1.0f; fg_color.b = 0.0f; /* Handle mission log event by its type */ switch(p_mission_log_event->event_type) { case SAR_MISSION_LOG_EVENT_COMMENT: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, NULL, /* No icon */ p_mission_log_event->message ); break; case SAR_MISSION_LOG_EVENT_POSITION: /* Was there a prior intercept marking? */ if(last_intercept_marking != NULL) { /* Set last intercept marking's end position * to the position specified by this log event */ last_intercept_marking->x_end = pos->x; last_intercept_marking->y_end = pos->y; } /* Create a new intercept line marking */ n = SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_INTERCEPT_LINE, &fg_color, pos->x, pos->y, pos->x, pos->y, NULL, /* No icon */ NULL /* No message */ ); /* Record pointer to this intercept line marking */ last_intercept_marking = (n > -1) ? map_ptr->marking[n] : NULL; /* Increment total number of intercept markings */ total_intercept_markings++; break; case SAR_MISSION_LOG_EVENT_TAKEOFF: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, core_ptr->menumap_helicopter_img, p_mission_log_event->message ); break; case SAR_MISSION_LOG_EVENT_LAND: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, core_ptr->menumap_helicopter_img, p_mission_log_event->message ); break; case SAR_MISSION_LOG_EVENT_CRASH: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, core_ptr->menumap_crash_img, p_mission_log_event->message ); break; case SAR_MISSION_LOG_EVENT_PICKUP: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, core_ptr->menumap_victim_img, p_mission_log_event->message ); break; case SAR_MISSION_LOG_EVENT_DROPOFF: SARMenuMapAppendMarking( map_ptr, SAR_MENU_MAP_MARKING_TYPE_ICON, &fg_color, pos->x, pos->y, 0.0f, 0.0f, core_ptr->menumap_helicopter_img, p_mission_log_event->message ); break; } } /* If this is the first event then set map's scroll * position to it */ if(total_events == 0) { map_ptr->scroll_x = (int)( -pos->x * map_ptr->m_to_pixels_coeff ); map_ptr->scroll_y = (int)( -pos->y * map_ptr->m_to_pixels_coeff ); map_ptr->selected_marking = 0; } total_events++; break; } } /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); free(title); free(scene_filename); free(player_stats_filename); } /* * Loads a new mission * * Note that the scene structure in the core structure must be * allocated and with all values reset. */ sar_mission_struct *SARMissionLoadFromFile( sar_core_struct *core_ptr, const char *filename, void *client_data, int (*progress_func)(void *, long, long) ) { int i, status, ptype, total_parms; void *p, **parm; sar_parm_version_struct *p_version; sar_parm_name_struct *p_name; sar_parm_description_struct *p_desc; sar_parm_player_model_file_struct *p_player_model_file; sar_parm_weather_struct *p_weather; sar_parm_time_of_day_struct *p_time_of_day; sar_parm_texture_base_directory_struct *p_texture_base_directory; sar_parm_texture_load_struct *p_texture_load; sar_parm_mission_new_objective_struct *p_mission_new_objective; sar_parm_mission_scene_file_struct *p_mission_scene_file; sar_parm_mission_time_left_struct *p_mission_time_left; sar_parm_mission_begin_at_struct *p_mission_begin_at; sar_parm_mission_begin_at_pos_struct *p_mission_begin_at_pos; sar_parm_mission_arrive_at_struct *p_mission_arrive_at; sar_parm_mission_message_success_struct *p_mission_message_success; sar_parm_mission_message_fail_struct *p_mission_message_fail; sar_parm_mission_humans_tally_struct *p_mission_humans_tally; sar_parm_mission_add_intercept_struct *p_mission_add_intercept; 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_fire_struct *p_new_fire; sar_parm_new_smoke_struct *p_new_smoke; sar_parm_new_premodeled_struct *p_new_premodeled; sar_parm_model_file_struct *p_model_file; 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_object_name_struct *p_object_name; 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; Boolean loaded_scene = False; sar_mission_struct *mission; int objective_num = -1; sar_mission_objective_struct *objective = NULL; int humans_need_rescue = 0; char *begin_at_name = NULL, *arrive_at_name = NULL, *weather_preset_name = NULL; int obj_num = -1; sar_object_struct *obj_ptr = NULL; 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; Boolean begin_at_set = False; sar_position_struct begin_pos; sar_direction_struct begin_dir; sar_scene_struct *scene = core_ptr->scene; sar_object_struct ***ptr = &core_ptr->object; int *total = &core_ptr->total_objects; const sar_option_struct *opt = &core_ptr->option; if((scene == NULL) || (filename == NULL)) return(NULL); /* Regets object substructure pointers from the specified object */ #define CONTEXT_REGET_SUBSTRUCTURE_PTRS(_o_) { \ if((_o_) != NULL) { \ obj_aircraft_ptr = SAR_OBJ_GET_AIRCRAFT(_o_); \ obj_ground_ptr = SAR_OBJ_GET_GROUND(_o_); \ obj_helipad_ptr = SAR_OBJ_GET_HELIPAD(_o_); \ obj_runway_ptr = SAR_OBJ_GET_RUNWAY(_o_); \ obj_human_ptr = SAR_OBJ_GET_HUMAN(_o_); \ obj_smoke_ptr = SAR_OBJ_GET_SMOKE(_o_); \ obj_fire_ptr = SAR_OBJ_GET_FIRE(_o_); \ } \ } /* Note, order of which parameters appear in the mission file * is important! We expect to parse certain parameters before * others in this function. */ /* Load parms from mission file */ status = SARParmLoadFromFile( filename, SAR_FILE_FORMAT_MISSION, &parm, &total_parms, -1, NULL, NULL ); if(status) return(NULL); if(opt->runtime_debug) printf( "SARMissionLoadFromFile(): Creating new mission...\n" ); /* Allocate a new mission structure */ mission = (sar_mission_struct *)calloc( 1, sizeof(sar_mission_struct) ); if(mission == NULL) { SARParmDeleteAll(&parm, &total_parms); return(NULL); } /* Set up default mission values */ mission->state = MISSION_STATE_IN_PROGRESS; mission->title = NULL; mission->description = NULL; mission->start_location_name = NULL; mission->scene_file = NULL; mission->player_model_file = NULL; mission->player_stats_file = NULL; mission->objective = NULL; mission->total_objectives = 0; mission->cur_objective = 0; /* Always start on first objective */ mission->time_spent = 0.0f; mission->check_int = 1000; /* In milliseconds */ mission->next_check = cur_millitime + mission->check_int; mission->log_position_int = 10000; mission->next_log_position = cur_millitime + mission->log_position_int; /* Iterate through loaded parms */ for(i = 0; i < total_parms; i++) { p = parm[i]; if(p == NULL) continue; /* Handle by parm type */ ptype = *(int *)p; 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.\n", 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(mission->title); mission->title = STRDUP(p_name->name); break; case SAR_PARM_DESCRIPTION: p_desc = (sar_parm_description_struct *)p; free(mission->description); mission->description = STRDUP(p_desc->description); break; case SAR_PARM_PLAYER_MODEL_FILE: p_player_model_file = (sar_parm_player_model_file_struct *)p; if(loaded_scene) { const char *player_file = p_player_model_file->file; char *full_path; /* Complete path */ if(ISPATHABSOLUTE(player_file)) { full_path = STRDUP(player_file); } else { struct stat stat_buf; full_path = STRDUP(PrefixPaths( dname.local_data, player_file )); if((full_path != NULL) ? stat(full_path, &stat_buf) : True) { free(full_path); full_path = STRDUP(PrefixPaths( dname.global_data, player_file )); } } if(full_path == NULL) fprintf( stderr, "%s: Warning: Unable to complete path \"%s\".\n", filename, player_file ); /* Update player model file name on mission and * core structures. */ free(mission->player_model_file); mission->player_model_file = STRDUP(full_path); free(core_ptr->cur_player_model_file); core_ptr->cur_player_model_file = STRDUP(full_path); /* Create the player object since the model file is * now known */ SARSceneAddPlayerObject( core_ptr, scene, full_path, &begin_pos, &begin_dir ); /* Update object context pointers */ obj_num = scene->player_obj_num; obj_ptr = scene->player_obj_ptr; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) free(full_path); } else { fprintf( stderr, "%s: \"player_model_file\" may not be specified before \"mission_scene_file\".\n", filename ); } break; case SAR_PARM_WEATHER: p_weather = (sar_parm_weather_struct *)p; if(loaded_scene) { fprintf( stderr, "%s: \"weather\" may not be specified after \"mission_scene_file\".\n", filename ); } else { free(weather_preset_name); weather_preset_name = STRDUP(p_weather->weather_preset_name); } break; case SAR_PARM_TIME_OF_DAY: p_time_of_day = (sar_parm_time_of_day_struct *)p; if(loaded_scene) { scene->tod = p_time_of_day->tod; #if 0 /* The tod_code is updated in SARSimUpdateScene() */ scene->tod_code = SAR_TOD_CODE_UNDEFINED; #endif } else { fprintf( stderr, "%s: \"time_of_day\" may not be specified before \"mission_scene_file\".\n", filename ); } 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; case SAR_PARM_MISSION_SCENE_FILE: p_mission_scene_file = (sar_parm_mission_scene_file_struct *)p; if(loaded_scene) { fprintf( stderr, "%s: Warning: Redefination of \"mission_scene_file\" ignored.\n", filename ); } else { const char *scene_file = p_mission_scene_file->file; char *full_path; /* Complete path */ if(ISPATHABSOLUTE(scene_file)) { full_path = STRDUP(scene_file); } else { struct stat stat_buf; full_path = STRDUP(PrefixPaths( dname.local_data, scene_file )); if((full_path != NULL) ? stat(full_path, &stat_buf) : True) { free(full_path); full_path = STRDUP(PrefixPaths( dname.global_data, scene_file )); } } if(full_path == NULL) fprintf( stderr, "%s: Warning: Unable to complete path \"%s\".\n", filename, scene_file ); /* Set new scene file on mission structure */ free(mission->scene_file); mission->scene_file = STRDUP(full_path); free(full_path); /* Load scene */ status = SARSceneLoadFromFile( core_ptr, scene, mission->scene_file, weather_preset_name, client_data, progress_func ); if(status) { /* Failed to load scene */ fprintf( stderr, "%s: Error occured while loading scene \"%s\".\n", filename, mission->scene_file ); SARSceneDestroy( core_ptr, scene, ptr, total ); SARMissionDelete(mission); mission = NULL; break; } else { loaded_scene = True; } } break; case SAR_PARM_MISSION_NEW_OBJECTIVE: p_mission_new_objective = (sar_parm_mission_new_objective_struct *)p; /* Create a new objective */ objective_num = mission->total_objectives; mission->total_objectives = objective_num + 1; mission->objective = (sar_mission_objective_struct *)realloc( mission->objective, mission->total_objectives * sizeof(sar_mission_objective_struct) ); if(mission->objective == NULL) { mission->total_objectives = 0; objective_num = -1; objective = NULL; } else { objective = &mission->objective[objective_num]; /* Clear and then set default objective structure values */ memset(objective, 0x00, sizeof(sar_mission_objective_struct)); objective->type = p_mission_new_objective->objective_type; objective->state = SAR_MISSION_OBJECTIVE_STATE_INCOMPLETE; objective->time_left = 0.0f; objective->humans_need_rescue = 0; objective->total_humans = 0; objective->arrive_at_name = NULL; objective->message_success = NULL; objective->message_fail = NULL; if(opt->runtime_debug) printf( "SARMissionLoadFromFile(): Creating new mission objective of type %i.\n", p_mission_new_objective->objective_type ); } break; case SAR_PARM_MISSION_TIME_LEFT: p_mission_time_left = (sar_parm_mission_time_left_struct *)p; if(objective != NULL) { objective->time_left = p_mission_time_left->time_left; } break; case SAR_PARM_MISSION_BEGIN_AT: p_mission_begin_at = (sar_parm_mission_begin_at_struct *)p; if(p_mission_begin_at->name != NULL) { sar_object_struct *begin_obj_ptr; /* Update mission begin at name */ free(begin_at_name); begin_at_name = STRDUP(p_mission_begin_at->name); free(mission->start_location_name); mission->start_location_name = STRDUP(p_mission_begin_at->name); if(!begin_at_set) { /* Match the object with the name specified by * begin_at_name. */ begin_obj_ptr = SARObjMatchPointerByName( scene, *ptr, *total, begin_at_name, NULL ); /* Got match? */ if(begin_obj_ptr != NULL) { /* Record begin at position and direction */ memcpy( &begin_pos, &begin_obj_ptr->pos, sizeof(sar_position_struct) ); /* TODO Need to work on getting begin_dir based on location of matched * begin_at_name object */ memcpy( &begin_dir, &begin_obj_ptr->dir, sizeof(sar_direction_struct) ); } else { fprintf( stderr, "%s: Warning: \"mission_begin_at\" object name \"%s\" not found.\n", filename, begin_at_name ); } begin_at_set = True; } } break; case SAR_PARM_MISSION_BEGIN_AT_POS: p_mission_begin_at_pos = (sar_parm_mission_begin_at_pos_struct *)p; if(!begin_at_set) { /* Record begin at position and direction */ memcpy( &begin_pos, &p_mission_begin_at_pos->pos, sizeof(sar_position_struct) ); memcpy( &begin_dir, &p_mission_begin_at_pos->dir, sizeof(sar_direction_struct) ); begin_at_set = True; } break; case SAR_PARM_MISSION_ARRIVE_AT: p_mission_arrive_at = (sar_parm_mission_arrive_at_struct *)p; if(p_mission_arrive_at->name != NULL) { sar_object_struct *arrive_obj_ptr; /* Update arrive_at_name context */ free(arrive_at_name); arrive_at_name = STRDUP(p_mission_arrive_at->name); /* Update arrive_at_name on current objective (if any) */ if(objective != NULL) { free(objective->arrive_at_name); objective->arrive_at_name = STRDUP(p_mission_arrive_at->name); } /* Match arrive at object (just to verify) */ arrive_obj_ptr = SARObjMatchPointerByName( scene, *ptr, *total, arrive_at_name, NULL ); if(arrive_obj_ptr == NULL) { fprintf( stderr, "%s: Warning: \"mission_arrive_at\" object name \"%s\" not found.\n", filename, arrive_at_name ); } } break; case SAR_PARM_MISSION_MESSAGE_SUCCESS: p_mission_message_success = (sar_parm_mission_message_success_struct *)p; if(p_mission_message_success->message != NULL) { /* Update message_success on current objective (if any) */ if(objective != NULL) { free(objective->message_success); objective->message_success = STRDUP(p_mission_message_success->message); } } break; case SAR_PARM_MISSION_MESSAGE_FAIL: p_mission_message_fail = (sar_parm_mission_message_fail_struct *)p; if(p_mission_message_fail->message != NULL) { /* Update message_fail on current objective (if any) */ if(objective != NULL) { free(objective->message_fail); objective->message_fail = STRDUP(p_mission_message_fail->message); } } break; case SAR_PARM_MISSION_HUMANS_TALLY: p_mission_humans_tally = (sar_parm_mission_humans_tally_struct *)p; if(objective != NULL) { objective->humans_need_rescue = p_mission_humans_tally->humans_need_rescue; objective->total_humans = p_mission_humans_tally->total_humans; /* Initial value humans_need_rescue cannot be * greater than total_humans. */ if(objective->humans_need_rescue > objective->total_humans) objective->humans_need_rescue = objective->total_humans; } break; case SAR_PARM_MISSION_ADD_INTERCEPT: p_mission_add_intercept = (sar_parm_mission_add_intercept_struct *)p; if(obj_ptr != NULL) { sar_intercept_struct intercept; sar_object_struct *tar_obj_ptr; /* Reset intercept structure */ memset(&intercept, 0x00, sizeof(sar_intercept_struct)); /* Handle by intercept reference code */ switch(p_mission_add_intercept->ref_code) { case 3: /* Intercept arrive at location */ tar_obj_ptr = SARObjMatchPointerByName( scene, *ptr, *total, arrive_at_name, NULL ); if(tar_obj_ptr != NULL) { intercept.x = tar_obj_ptr->pos.x; intercept.y = tar_obj_ptr->pos.y; intercept.z = tar_obj_ptr->pos.z; intercept.radius = p_mission_add_intercept->radius; intercept.urgency = p_mission_add_intercept->urgency; } break; case 2: /* Intercept begin at location */ tar_obj_ptr = SARObjMatchPointerByName( scene, *ptr, *total, begin_at_name, NULL ); if(tar_obj_ptr != NULL) { intercept.x = tar_obj_ptr->pos.x; intercept.y = tar_obj_ptr->pos.y; intercept.z = tar_obj_ptr->pos.z; intercept.radius = p_mission_add_intercept->radius; intercept.urgency = p_mission_add_intercept->urgency; } break; default: /* Standard intercept */ intercept.x = p_mission_add_intercept->pos.x; intercept.y = p_mission_add_intercept->pos.y; intercept.z = p_mission_add_intercept->pos.z; intercept.radius = p_mission_add_intercept->radius; intercept.urgency = p_mission_add_intercept->urgency; break; } /* Allocate new intercept structure on object */ if(obj_aircraft_ptr != NULL) { SARObjInterceptNew( scene, &obj_aircraft_ptr->intercept, &obj_aircraft_ptr->total_intercepts, intercept.flags, intercept.x, intercept.y, intercept.z, intercept.radius, intercept.urgency, intercept.name ); } } break; case SAR_PARM_NEW_OBJECT: p_new_object = (sar_parm_new_object_struct *)p; /* Create new object of the specified type */ obj_num = SARObjNew( scene, ptr, total, p_new_object->object_type ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) break; case SAR_PARM_NEW_HELIPAD: p_new_helipad = (sar_parm_new_helipad_struct *)p; /* Create new helipad */ obj_num = SARObjLoadHelipad( core_ptr, scene, p_new_helipad ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) break; case SAR_PARM_NEW_RUNWAY: p_new_runway = (sar_parm_new_runway_struct *)p; /* Create new runway */ obj_num = SARObjLoadRunway( core_ptr, scene, p_new_runway ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) break; case SAR_PARM_NEW_HUMAN: p_new_human = (sar_parm_new_human_struct *)p; /* Create new human */ obj_num = SARObjLoadHuman( core_ptr, scene, p_new_human ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) if((obj_ptr != NULL) && (obj_human_ptr != NULL)) { /* Increment number of humans that need rescue that * this mission file has specified. */ if(obj_human_ptr->flags & SAR_HUMAN_FLAG_NEED_RESCUE) humans_need_rescue++; } break; case SAR_PARM_NEW_FIRE: p_new_fire = (sar_parm_new_fire_struct *)p; /* Create new fire object */ obj_num = SARObjLoadFire( core_ptr, scene, p_new_fire ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) break; case SAR_PARM_NEW_SMOKE: p_new_smoke = (sar_parm_new_smoke_struct *)p; /* Create new smoke trails object */ obj_num = SARObjLoadSmoke( core_ptr, scene, p_new_smoke ); /* Update object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) break; case SAR_PARM_NEW_PREMODELED: p_new_premodeled = (sar_parm_new_premodeled_struct *)p; /* Create new premodeled object */ obj_num = SARObjPremodeledNew( core_ptr, scene, p_new_premodeled->model_type, p_new_premodeled->argc, p_new_premodeled->argv ); /* Reget object context pointers */ obj_ptr = (obj_num > -1) ? (*ptr)[obj_num] : NULL; CONTEXT_REGET_SUBSTRUCTURE_PTRS(obj_ptr) 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; #if 0 case SAR_PARM_SELECT_OBJECT_BY_NAME: p_select_object_by_name = (sar_parm_select_object_by_name_struct *)p; if(p_select_object_by_name->name != NULL) { obj_ptr = SARObjMatchPointerByName( scene, core_ptr->object, core_ptr->total_objects, p_select_object_by_name->name, &obj_num ); } break; #endif 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; SARObjLoadTranslateRandom( core_ptr, scene, obj_ptr, p_translate_random ); 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_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_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 = 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; default: break; } /* Handle by parm type */ /* If we lost the mission structure then we need to * give up, there was probably some fatal error * encountered above */ if(mission == NULL) break; } /* Iterate through loaded parms */ /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); if(opt->runtime_debug) printf( "SARMissionLoadFromFile():\ Loaded new mission with %i objectives.\n", mission->total_objectives ); free(begin_at_name); free(arrive_at_name); free(weather_preset_name); #undef CONTEXT_REGET_SUBSTRUCTURE_PTRS return(mission); } /* * Resets the mission log file specified by filename and rewrites * its header with the information given by the mission structure. * * This will overwrite the previous log file (if any) specified * by filename. */ void SARMissionLogReset( sar_core_struct *core_ptr, sar_mission_struct *mission, const char *filename /* Mission log file name */ ) { void *p, **parm = NULL; int total_parms = 0; if((mission == NULL) || STRISEMPTY(filename)) return; /* Begin generating parameters for writing mission log */ p = SARParmNewAppend( SAR_PARM_MISSION_LOG_HEADER, &parm, &total_parms ); if(p != NULL) { sar_parm_mission_log_header_struct *pv = (sar_parm_mission_log_header_struct *)p; pv->version_major = PROG_VERSION_MAJOR; pv->version_minor = PROG_VERSION_MINOR; pv->version_release = PROG_VERSION_RELEASE; free(pv->title); pv->title = STRDUP(mission->title); free(pv->scene_file); pv->scene_file = STRDUP(mission->scene_file); free(pv->player_stats_file); pv->player_stats_file = STRDUP(mission->player_stats_file); } /* Write mission log file, this will overwrite the existing * mission log file (if any). */ SARParmSaveToFile( filename, SAR_FILE_FORMAT_MISSION_LOG, parm, total_parms, NULL, NULL ); /* Delete loaded parms */ SARParmDeleteAll(&parm, &total_parms); } /* * Appends a log entry to the given log file, the log file will be * opened for writing (append) and then closed during this call. * * The event_type must be given and cannot be -1. * * The tod (time of day) can be either a valid time or -1.0 to indicate * use current time on core's scene structure. * * The given file name must reffer to valid file which is writeable. * * All other inputs are optional. */ void SARMissionLogEvent( sar_core_struct *core_ptr, sar_mission_struct *mission, int event_type, /* One of SAR_LOG_EVENT_* */ float tod, /* Time of day in seconds since midnight */ sar_position_struct *pos, /* Position of event */ const float *value, /* Additional values */ int total_values, /* Total number of additional values */ const char *message, /* The message */ const char *filename /* Mission log file name */ ) { int i; FILE *fp; sar_scene_struct *scene = core_ptr->scene; if((scene == NULL) || (mission == NULL) || STRISEMPTY(filename) ) return; /* Open mission log file for append writing */ fp = FOpen(filename, "ab"); if(fp == NULL) return; /* Write event type, time and coordinates */ fprintf( fp, "%i %f %f %f %f%s", event_type, (tod < 0.0f) ? scene->tod : tod, (pos != NULL) ? pos->x : 0.0f, (pos != NULL) ? pos->y : 0.0f, (pos != NULL) ? pos->z : 0.0f, (total_values > 0) ? " " : "" ); /* Write any additional arguments */ for(i = 0; i < total_values; i++) fprintf( fp, "%f%s", value[i], (i < (total_values - 1)) ? " " : "" ); /* Write values and message deliminator character */ fputc(':', fp); /* Write message? */ if(message != NULL) fputs(message, fp); /* End this log event line with a newline character */ fputc('\n', fp); /* Close mission log file */ FClose(fp); } searchandrescue_1.5.0/sar/sfmmodel.h0000644000175000017500000001355110104532751016511 0ustar jessejesse/* SAR Flight Model - Flight Dynamics Model Contains the flight dyanmics parameters for simulation of each model. When adding a parameter, make sure the functions; SFMModelChangeValues() and SFMModelUndefineValue() get updated to support the new parameter. */ #ifndef SFMMODEL_H #define SFMMODEL_H #include "sfmtypes.h" /* * Flight model defined parameter flags: */ #define SFMFlagFlightModelType ((SFMFlags)1 << 0) #define SFMFlagPosition ((SFMFlags)1 << 1) #define SFMFlagDirection ((SFMFlags)1 << 2) #define SFMFlagVelocityVector ((SFMFlags)1 << 3) #define SFMFlagSpeed ((SFMFlags)1 << 4) #define SFMFlagSpeedStall ((SFMFlags)1 << 5) #define SFMFlagDragMin ((SFMFlags)1 << 6) #define SFMFlagSpeedMax ((SFMFlags)1 << 7) /* And overspeed_expected and overspeed. */ #define SFMFlagAccelResponsiveness ((SFMFlags)1 << 8) #define SFMFlagGroundElevation ((SFMFlags)1 << 9) #define SFMFlagServiceCeiling ((SFMFlags)1 << 10) #define SFMFlagBellyHeight ((SFMFlags)1 << 11) #define SFMFlagGearState ((SFMFlags)1 << 12) /* Landing gear state. */ #define SFMFlagGearType ((SFMFlags)1 << 13) #define SFMFlagGearHeight ((SFMFlags)1 << 14) #define SFMFlagGearBrakesState ((SFMFlags)1 << 15) #define SFMFlagGearTurnVelocityOptimul ((SFMFlags)1 << 16) #define SFMFlagGearTurnVelocityMax ((SFMFlags)1 << 17) #define SFMFlagGearTurnRate ((SFMFlags)1 << 18) #define SFMFlagLandedState ((SFMFlags)1 << 19) #define SFMFlagGroundContactType ((SFMFlags)1 << 20) #define SFMFlagHeadingControlCoeff ((SFMFlags)1 << 21) #define SFMFlagBankControlCoeff ((SFMFlags)1 << 22) #define SFMFlagPitchControlCoeff ((SFMFlags)1 << 23) #define SFMFlagThrottleCoeff ((SFMFlags)1 << 24) #define SFMFlagAfterBurnerState ((SFMFlags)1 << 25) #define SFMFlagAfterBurnerPowerCoeff ((SFMFlags)1 << 26) #define SFMFlagEnginePower ((SFMFlags)1 << 27) #define SFMFlagTotalMass ((SFMFlags)1 << 28) #define SFMFlagAttitudeChangeRate ((SFMFlags)1 << 29) #define SFMFlagAttitudeLevelingRate ((SFMFlags)1 << 30) #define SFMFlagAirBrakesState ((SFMFlags)1 << 31) #define SFMFlagAirBrakesRate ((SFMFlags)1 << 32) #define SFMFlagCanCrashIntoOther ((SFMFlags)1 << 33) #define SFMFlagCanCauseCrash ((SFMFlags)1 << 34) #define SFMFlagCrashContactShape ((SFMFlags)1 << 35) #define SFMFlagCrashableSizeRadius ((SFMFlags)1 << 36) #define SFMFlagCrashableSizeZMin ((SFMFlags)1 << 37) #define SFMFlagCrashableSizeZMax ((SFMFlags)1 << 38) #define SFMFlagTouchDownCrashResistance ((SFMFlags)1 << 39) #define SFMFlagCollisionCrashResistance ((SFMFlags)1 << 40) /* * Flight model types: */ #define SFMFlightModelAirplane 0 #define SFMFlightModelHelicopter 1 #define SFMFlightModelSlew 2 /* * Landing gear types: */ #define SFMGearTypeWheels 0 #define SFMGearTypeSkis 1 #define SFMGearTypeFloats 2 /* * Ground types: */ #define SFMGroundTypeLandUnpaved 0 #define SFMGroundTypeLandPaved 1 #define SFMGroundTypeWaterCalm 2 #define SFMGroundTypeWaterRough 3 /* * Crash contact shapes: */ #define SFMCrashContactShapeSpherical 0 #define SFMCrashContactShapeCylendrical 1 /* * Flight Dynamics Model structure: * * Generally, units for position are in meters and * velocity/speed/rate are in meters per cycle. */ typedef struct { /* Flags indicating which parameters (members in the * structure) are defined (non-garbage). Since the * SFMFlags type has up to 64 bits, we can have up to * 64 defineable members in this structure, use them * wisely! Members marked as `internal' do not have * an associated flag. */ SFMFlags flags; int type; /* One of SFMFlightModel*. */ SFMPositionStruct position; /* Meters. */ SFMDirectionStruct direction; /* Radians. */ SFMPositionStruct velocity_vector; /* Meters/cycle. */ SFMPositionStruct slew_velocity_vector; /* Internal, used only * when type is set to * SFMFlightModelSlew. */ double speed; /* Meters/cycle. */ double speed_stall, /* Meters/cycle. */ stall_coeff; /* Internal. */ double drag_min; /* Meters/cycle. */ double speed_max; /* Meters/cycle. */ double overspeed_expected; /* Meters/cycle. */ double overspeed; /* Meters/cycle. */ SFMPositionStruct accel_responsiveness; double ground_elevation_msl; /* Meters. */ double service_ceiling; /* Meters. */ double belly_height; /* Undercarrage to center, meters. */ SFMBoolean gear_state; /* True when down. */ int gear_type; /* One of SFMGearType*. */ double gear_height; /* Meters. */ SFMBoolean gear_brakes_state; double gear_turn_velocity_optimul; /* Meters/cycle. */ double gear_turn_velocity_max; /* Meters/cycle. */ double gear_turn_rate; SFMBoolean landed_state; /* True if landed. */ int ground_contact_type; /* One of SFMGroundType*. */ double center_to_ground_height; /* Internal, center of * object to touchable * ground height, * in meters. */ double heading_control_coeff; /* -1.0 to 1.0. */ double pitch_control_coeff; /* -1.0 to 1.0. */ double bank_control_coeff; /* -1.0 to 1.0. */ double elevator_trim_coeff; /* -1.0 to 1.0. */ double throttle_coeff; /* 0.0 to 1.0. */ SFMBoolean after_burner_state; double after_burner_power_coeff; /* Times engine power. */ double engine_power; /* In kg * m / cycle^2. */ double total_mass; /* In kg. */ SFMDirectionStruct attitude_change_rate; /* Radians/cycle, */ SFMDirectionStruct attitude_leveling_rate; /* Radians/cycle. */ SFMBoolean air_brakes_state; double air_brakes_rate; /* In meters per cycle. */ SFMBoolean can_crash_into_other; SFMBoolean can_cause_crash; int crash_contact_shape; /* One of SFMCrashContactShape*. */ double crashable_size_radius; /* Meters. */ double crashable_size_z_min; /* Meters. */ double crashable_size_z_max; /* Meters. */ double touch_down_crash_resistance; /* Meters/cycle. */ double collision_crash_resistance; /* Meters/cycle. */ } SFMModelStruct; #endif /* SFMMODEL_H */ searchandrescue_1.5.0/sar/v3dmh.h0000644000175000017500000000541510104532752015725 0ustar jessejesse/* V3D Model Header Items Data types for basic 3D model header items. When adding new types, make sure you update V3DMHCreate() to allocate the correct size of the data type structure and update MV3DHDestroy() to deallocate and members that may point to allocated resources. Externally, you may need to update other functions. */ #ifndef V3DMH_H #define V3DMH_H #include #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Model header item types: */ #define V3DMH_TYPE_COMMENT 1 #define V3DMH_TYPE_VERSION 10 #define V3DMH_TYPE_CREATOR 11 #define V3DMH_TYPE_AUTHOR 12 #define V3DMH_TYPE_HEIGHTFIELD_BASE_DIRECTORY 20 #define V3DMH_TYPE_TEXTURE_BASE_DIRECTORY 21 #define V3DMH_TYPE_TEXTURE_LOAD 22 #define V3DMH_TYPE_COLOR_SPECIFICATION 30 /* * Model header item structures: */ /* Comment. */ typedef struct { int type; /* Must be V3DMH_TYPE_COMMENT. */ char **line; int total_lines; } mh_comment_struct; /* Version. */ typedef struct { int type; /* Must be V3DMH_TYPE_VERSION. */ int major, minor; } mh_version_struct; /* Creator. */ typedef struct { int type; /* Must be V3DMH_TYPE_CREATOR. */ char *creator; } mh_creator_struct; /* Author. */ typedef struct { int type; /* Must be V3DMH_TYPE_AUTHOR. */ char *author; } mh_author_struct; /* Heightfield base directory. */ typedef struct { int type; /* Must be V3DMH_TYPE_HEIGHTFIELD_BASE_DIRECTORY. */ char *path; } mh_heightfield_base_directory_struct; /* Texture base directory. */ typedef struct { int type; /* Must be V3DMH_TYPE_TEXTURE_BASE_DIRECTORY. */ char *path; } mh_texture_base_directory_struct; /* Texture load. */ typedef struct { int type; /* Must be V3DMH_TYPE_TEXTURE_LOAD. */ char *name, *path; double priority; /* 0.0 to 1.0. */ } mh_texture_load_struct; /* Color specification. */ typedef struct { int type; /* Must be V3DMH_TYPE_COLOR_SPECIFICATION. */ char *name; double a, r, g, b; double ambient, diffuse, specular, shininess, emission; } mh_color_specification_struct; extern void *V3DMHCreate(int type); extern void V3DMHDestroy(void *p); #define V3DMHGetType(p) (*(int *)p) extern void *V3DMHListGetPtr(void **list, int total, int i); extern void *V3DMHListInsert( void ***list, int *total, int i, int type ); extern void V3DMHListDelete(void ***list, int *total, int i); extern void V3DMHListDeleteAll(void ***list, int *total); extern int V3DMHTextureBaseDirectorySet( void ***list, int *total, const char *path ); extern char *V3DMHTextureBaseDirectoryGet(void **list, int total); extern int V3DMHHeightfieldBaseDirectorySet( void ***list, int *total, const char *path ); extern char *V3DMHHeightfieldBaseDirectoryGet(void **list, int total); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* V3DMH_H */ searchandrescue_1.5.0/sar/Makefile.srclist0000644000175000017500000000507611351227714017664 0ustar jessejesseSRC_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.5.0/sar/icons/0000755000175000017500000000000010104532745015643 5ustar jessejessesearchandrescue_1.5.0/sar/icons/SearchAndRescue5.ico0000644000175000017500000000566610104532745021440 0ustar jessejesse & ( @( @ʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___wwwmmmCCCmCCCCmCCCmCCDDmCCCmDmCCCCDDmmnCCCCDmKnomCCCCDDDDhnnmmCCCDDDEnnmCCCDEnnmCEnomCnomnnCmmChnmCmmmmCCCCmmCCC CCC CCCCCCC CCsearchandrescue_1.5.0/sar/icons/SearchAndRescue.ico0000644000175000017500000000566610104532745021353 0ustar jessejesse & ( @( @ʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___wwwlfllfllllefllffflllflflllflfffflllffellffllflllllfffflffffflllllflllfefelflllllllflefleff J#leeellllllllllllllffCC##llfeeeleeflllfCC틋lfllflfllleelfffffffC $E$ffffllffffllfCffllllflf $"$$ffflfllCCFF$$$lllllfllfCGGGGF%%%%fllflfflllM %FF%FllffflFGFFo"Gff F D GGlffu % F%>lllfllfꋋ%FE$lflꋋG$$l$F$C$offfuGnL%$$$$searchandrescue_1.5.0/sar/icons/SearchAndRescue2.ico0000644000175000017500000000427610104532745021431 0ustar jessejesse ( @xXPXx|\T\D44<|t00PP|tx 00Xlplļ884hLL|pdؼTLLĴ||((hhx,,(HHxtlhd((`ld\pXXȜ Pxx$$``00HԴ8@D@@xx@@|м`XPxxpthȼpp8((phhhdh̨̨8@@P@@pXPxp@@@@!!@@!!!@@@@@@@@@@@@@@EEE,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*66,6666,,,,,,66,,,6666666766,666=66766666666H=H7666=0600=07667=66666==06H06766==C < 5H6666676=0==C. ;5)3666==0H66===0==0H$<<< ?G000=76K0=077 "%(+ 2===00=I7%77+-((50=0=0/A0==7777+(J+000=/A006BBGG(("""7H=0055>@L< "+L1L'IH==0000HI'''LLL&LLLLLIH0=H000II''LL""LLL1!#MMD" %H000000I'LLLL8#L1L1111LLLLLB00000H''L118!&11111111LLLL7H00HL11!#1111111LLL'00IL18!FN41111LL0HIL11FF 1LLLIHIL11188888888891111888888888898111188888888888888889988881188988888888888888889998989:88:8:81999988898888889998989:8998881899888898888889998988988888899:8888999999999988899:98899999999819988899999999LLLLLsearchandrescue_1.5.0/sar/icons/SearchAndRescue4.ico0000644000175000017500000001515610104532745021432 0ustar jessejesse 600 ( @fffffffffffhfhfffffffffffffhffwwwwwwwwwwwwwwwwwwwwwwwwwwxQwwywqwwwywyxxwwwwwxwwwwwwwwwwywwwwwwwxxwwwwwywwwwxwwwwwxywwwwxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww(0` ʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___www onnnnnnnnݶ nE$$EEEEEEEEEFFFFEDDCoFnnhE>nnEFFFFFFgEFFFFFDCFFFFFhFDFFGFFFggEFEgEDCmGGFFGGE EFEEFE$FmmhFEn 4GGoGGGGGFFiniFEhnohhGGݓnEFFFGGFFGGGGFoGGGoݶEFFFFnFFFGGFFFo  F oo  F mﻻFF   GG ( @ʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___wwwllllllllllllllllllllllllllllllllllllllllonnnnnݓonnE>E%%%EF%F>CFF%FFDFFFFDEDDEC FooFFFFFhEEEnEݶFݼhEFFFFGGFo FFF FFFo o oo FF  FG searchandrescue_1.5.0/sar/icons/SearchAndRescue3.ico0000644000175000017500000001256610104532745021433 0ustar jessejesse &  ( @ _o_o_o_o_o_o_o_o_o_o_o_o_w_o_o_o_o_oo_o_o_o_o_o_o_o`w_o_o_o_o_o_o_w_w_w_w_w_w_w_w_w_w_w`_w_w_o_o_o`w_o_o_o_o_o_o_oo_o_o_o_o_o_w_w_w_w_w_w_w_w_w_w_w_w`_w_w_w_w_o_o_o_o_o_o_o_o_oo_o_o_o_o_o`w_PPP_____PP_P_w_w_w_w_w_wo_o_o_o_w`w`w_o_o_o_o_o``____________PP_w_w_w_w_wooo`w_oo_o_o_o_o_o`````________o___PP_w_w_w_w_o_o`w`w_o_o_o_o_o```````______``___P_w_w_w_w_o_oo_o_o_o_o_o_o``````_wOgoO_`@W_@W__wPwPopPop_w@go@_`@_`@_o?W_@_`@W_O_oPgp?O_?OP/0???OO_o@W_@W__`````oPgoO_`_op@W_0G@?OOO_`Og`_opoO_`Po____`__o_o_o_oPoPo_o```oooo_w@W_/70?OO@O@0G@/70070@70@G@````___w_w_w_w_o_oPoPo_oooooooo' ?OO@OO@OO@7/?' 0??_opOg`_w_w_o_w_o_w_o_oPoPoPo0G@?GO?GO?OO?OO/?0/?0 // //' //@OOO???//'  /' '/ '/ '/?OO@OO@OO@OO?OO0??0G@0G@/70' //O__O__OG?0//@WP@WP@WPO__@WP0G@0G@0G@0G@@O@`ooopopO__@WPO70P7/ ///?0/?0 // 7 ' ' ' /70//0//@WP@WPP_PO__@WP0??0G@/??0??/70/70O__O__OW_OW_@OOP//' ' 070/70 '  ' ??O@OO@WP@WP@WP/70/70/??/??/70/70/70/70 // // // //' '  //' ' /?00GO0G@?OO?OO?OO?OO?OO?OO?GO0G@/700??/70 // // // 7 7 ' ' /70/// // ' ' _g`/??0GO?G_0GO@__O_`O_`Og`O__O__@WP@WP@OO@O@0G@0G?0G@0??/??/70/7//70 // ' ' ' ' '  ' _O@@O@0G@?OP0OP0OP0OP0GO0OP@W_O_`Pg`Pg`Pg`Pg`O__P_P@OP@OO@O@0??/70/70 //' ' ' _WOog_пппppO_o?_`?_`?__?_P0O_?W_@Wo@Wo?W_?W_?W_?O_0GO0GOoo`pпппϷPwPwp@go@_o@_`@_`PgoPg`__o`ooпϷϷǰǰǿǰǰǰϷϷпппппǰǰǿǰǰϷϷпппϷǰǰǿǰǰǰпппппǰǰǿǿǰǰппϷǰǰǿǿǿǰǿǿǰǰпп( @ʦ """)))UUUMMMBBB999|PP3f3333f333ff3fffff3f3f̙f3333f3333333333f3333333f3f33ff3f3f3f3333f3333333f3̙33333f333ff3ffffff3f33f3ff3f3f3ffff3fffffffff3fffffff3f̙ffff3ff333f3ff33fff33f3ff̙3f3f3333f333ff3fffff̙̙3̙f̙̙̙3f̙3f3f3333f333ff3fffff3f3f̙3ffffffffff!___wwwmmmmmmmmmmmmnmmmmmmmmmmmmmmmmmmnnnnnnnnnnnnnnmmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnnmmmmmmmmmmmmmmnnnnnnnnnnnnnnnnnnmmmmmmmmnnnnnnnnnnnnnnnnnnnnnmmmmmmnnnnnnnnnnnnnsnnnnnnnnnmmmmmmmnnnnssnnnnnnnssnnnnnnnnmmmmmmmmssssssnmmmnJJJJJJmCnnssssmmmnnnnsmmmmmmmsssssCCCnsssnnnnnnmmmmmsssmnmnmnmmmmmCCC CC mfCCCC CCfCCCCCCCC CCC CDCCCCCmJJJJDJJJJJJmﵵmmJJJJmﵵﵵﻻﵵsearchandrescue_1.5.0/sar/icons/SearchAndRescue.xpm0000644000175000017500000007756011443525312021406 0ustar jessejesse/* 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.5.0/sar/icons/SearchAndRescue3.xpm0000644000175000017500000007336110104532745021465 0ustar jessejesse/* XPM */ static char * SearchAndRescue3_xpm[] = { "48 48 1599 2", " c None", ". c #A7BAC7", "+ c #A5B7C6", "@ c #A6B6C7", "# c #A7B6C7", "$ c #A8B6C7", "% c #A9B7C7", "& c #A9B8C7", "* c #A9BAC7", "= c #A9BAC8", "- c #AABAC8", "; c #AABBC8", "> c #A9BBC8", ", c #A8B8C7", "' c #A7B7C7", ") c #A6B6C6", "! c #A5B4C5", "~ c #A5B5C5", "{ c #A4B4C5", "] c #A3B6C5", "^ c #A4B6C4", "/ c #A3B5C4", "( c #A0B5C3", "_ c #A0B5C2", ": c #9FB3C2", "< c #9EB1C2", "[ c #9DAFC1", "} c #9CADC0", "| c #9BAEBF", "1 c #9AADBE", "2 c #9AACBE", "3 c #99AEBD", "4 c #98AEBC", "5 c #99ADBC", "6 c #99ADBB", "7 c #98ACBA", "8 c #98ADBB", "9 c #9BAFBB", "0 c #99AEBA", "a c #98A9BA", "b c #93A5BA", "c c #90A4B8", "d c #8DA0B7", "e c #869DB8", "f c #859FB7", "g c #A4B4C6", "h c #A5B5C6", "i c #A6B4C6", "j c #A7B4C6", "k c #AAB7C8", "l c #ACB9C9", "m c #AEBBCA", "n c #AFBEC9", "o c #B0BDC9", "p c #AFBEC8", "q c #AEBEC7", "r c #AEBDC8", "s c #ACBAC8", "t c #ACBBC8", "u c #A6B9C6", "v c #A7B9C6", "w c #AAB9C6", "x c #ADB8C5", "y c #A9B7C4", "z c #A3B6C3", "A c #9FB5C2", "B c #9EB4C2", "C c #9DB3C1", "D c #9DB2C1", "E c #9CB1BF", "F c #9BB1BF", "G c #9BB0BE", "H c #9EAFBE", "I c #9BAFBD", "J c #9DAFBD", "K c #A3B0BE", "L c #A5B1BE", "M c #A6B2BE", "N c #A5B2BE", "O c #9AAEBC", "P c #97A8B9", "Q c #95A6B7", "R c #8EA3B8", "S c #89A0B9", "T c #889DB9", "U c #A3B4C5", "V c #AAB8C8", "W c #ABB8C9", "X c #ADB9C8", "Y c #AFBBC8", "Z c #B0BCC9", "` c #B1BEC9", " . c #B2C0C9", ".. c #B1C0C8", "+. c #B0BEC8", "@. c #AFBEC7", "#. c #ACBCC8", "$. c #A8BAC7", "%. c #A7BAC6", "&. c #A5B9C5", "*. c #A3B8C5", "=. c #A1B4C4", "-. c #A0B1C3", ";. c #A0B0C3", ">. c #9FB2C2", ",. c #9EB2C0", "'. c #A4B0BF", "). c #A1B0BE", "!. c #9DB1BE", "~. c #A1B2BF", "{. c #A7B3C0", "]. c #A6B2BF", "^. c #A3AEBC", "/. c #9DACBB", "(. c #95ABBA", "_. c #94A7B8", ":. c #94A6B7", "<. c #91A4B7", "[. c #8FA3B8", "}. c #8EA1B7", "|. c #8B9EBA", "1. c #879CBA", "2. c #A7B6C9", "3. c #A7B4CA", "4. c #A8B5C9", "5. c #AAB7C9", "6. c #ABB9CB", "7. c #ACB9CA", "8. c #ADBAC9", "9. c #ABBCCE", "0. c #ACBDCF", "a. c #ACBED2", "b. c #AFBFCF", "c. c #AFBFD1", "d. c #B1BFCD", "e. c #B1BFCA", "f. c #B0BFC9", "g. c #AFBFC7", "h. c #ADBDC8", "i. c #ADBBC9", "j. c #ADBAC8", "k. c #AABAC6", "l. c #A4B8C5", "m. c #A3B5C5", "n. c #A2B5C4", "o. c #A3B6C4", "p. c #A3B5C3", "q. c #A3B4C1", "r. c #A3B2C0", "s. c #A5B3C1", "t. c #A2B4C1", "u. c #A3AFBE", "v. c #A1AEBD", "w. c #9FADBC", "x. c #99ACBA", "y. c #97ABB9", "z. c #95A7BB", "A. c #93A4BE", "B. c #90A1C1", "C. c #90A1C2", "D. c #8E9FBE", "E. c #8C9CC2", "F. c #A6B7C6", "G. c #A9B7C8", "H. c #ABB7D0", "I. c #ADB9D0", "J. c #AFBBC9", "K. c #AFBCCA", "L. c #AEBECD", "M. c #AFC1CF", "N. c #B0C2D0", "O. c #B3C3D1", "P. c #B4C3CF", "Q. c #B4C2CE", "R. c #B2C1CB", "S. c #B2C3CB", "T. c #B1C2CA", "U. c #B0C1C9", "V. c #B0BBC9", "W. c #B0BAC9", "X. c #AFBAC7", "Y. c #AEBBC7", "Z. c #ABB9C5", "`. c #AAB7C4", " + c #A8B6C3", ".+ c #A6B5C3", "++ c #A9B5C2", "@+ c #AAB4C1", "#+ c #A4B2C0", "$+ c #A0AFBD", "%+ c #9FAEBD", "&+ c #A0AEBD", "*+ c #9BADBB", "=+ c #96ACBA", "-+ c #97A9BE", ";+ c #98A8BE", ">+ c #97A8BF", ",+ c #95A5C3", "'+ c #93A4C2", ")+ c #90A2BF", "!+ c #899CBD", "~+ c #A5B6C6", "{+ c #A7B6C6", "]+ c #AEBACC", "^+ c #B0BCCF", "/+ c #B2BFCB", "(+ c #B3C2CC", "_+ c #B5C4CC", ":+ c #B8C5D1", "<+ c #B9C5D1", "[+ c #BBC7CE", "}+ c #BEC8CB", "|+ c #BCC8CA", "1+ c #B9C6CA", "2+ c #B5C4CB", "3+ c #B5C3CB", "4+ c #B7C3CA", "5+ c #B6C1CA", "6+ c #B6C0C9", "7+ c #B5BECB", "8+ c #B4BDCB", "9+ c #B2BCC9", "0+ c #B0BBC7", "a+ c #AFBAC6", "b+ c #AEB9C5", "c+ c #ADB8C4", "d+ c #ACB7C4", "e+ c #AAB5C3", "f+ c #A9B4C2", "g+ c #A8B3C1", "h+ c #A7B2C0", "i+ c #A6B0C0", "j+ c #A5B0BF", "k+ c #A1AFBD", "l+ c #9DAEBD", "m+ c #99AEBB", "n+ c #97ABBB", "o+ c #97A8BE", "p+ c #94A9BD", "q+ c #92A8BA", "r+ c #8DA6BA", "s+ c #88A1B9", "t+ c #85A0BB", "u+ c #839FBA", "v+ c #819CBC", "w+ c #ADBAC7", "x+ c #B2BFCD", "y+ c #B4C2D0", "z+ c #B7C4CE", "A+ c #B8C5CC", "B+ c #C0CBD5", "C+ c #C8D4DD", "D+ c #CDDCDB", "E+ c #CFDDDB", "F+ c #CEDAD9", "G+ c #CAD3D4", "H+ c #C3CACD", "I+ c #BEC6CC", "J+ c #BCC4CB", "K+ c #BFC4CB", "L+ c #C0C4CA", "M+ c #C1C5CA", "N+ c #C0C5CD", "O+ c #BEC4CB", "P+ c #BCC2CA", "Q+ c #B9BFC8", "R+ c #B5BDC6", "S+ c #B4BCC6", "T+ c #B3BBC5", "U+ c #AEB8C4", "V+ c #ADB6C3", "W+ c #ABB5C2", "X+ c #AFB8C3", "Y+ c #AEB7C2", "Z+ c #A9B3BF", "`+ c #A5B0BE", " @ c #9BADBC", ".@ c #96AABA", "+@ c #94A7BC", "@@ c #90A7BA", "#@ c #8CA6BD", "$@ c #8AA5BA", "%@ c #85A1BB", "&@ c #84A0C1", "*@ c #819DC2", "=@ c #AEBCC9", "-@ c #AEBBC9", ";@ c #B3BEC8", ">@ c #B4C0C9", ",@ c #B4C3C9", "'@ c #B7C4CA", ")@ c #B9C6CB", "!@ c #C4D1D5", "~@ c #D1DEDE", "{@ c #DEE9E5", "]@ c #E9F2E8", "^@ c #EBF2E9", "/@ c #E6EEE6", "(@ c #DEE5E0", "_@ c #D1DAD9", ":@ c #C6CDCF", "<@ c #C3C7CD", "[@ c #C4C6CC", "}@ c #C2C5CB", "|@ c #C4C9CC", "1@ c #C2C6CC", "2@ c #BEC2CB", "3@ c #BBC1C9", "4@ c #BBC0C9", "5@ c #BABFC8", "6@ c #BAC0C8", "7@ c #BBC2C9", "8@ c #B9C0C7", "9@ c #B7BDC6", "0@ c #B0B8C3", "a@ c #ABB4C1", "b@ c #A8B2BF", "c@ c #A4AFBE", "d@ c #A2AEBE", "e@ c #9AADBD", "f@ c #96ACBC", "g@ c #96A8C2", "h@ c #93A7C1", "i@ c #8EA7BB", "j@ c #8BA5BE", "k@ c #86A2BE", "l@ c #809DBF", "m@ c #ABBBCB", "n@ c #ADBDCA", "o@ c #B1BFC9", "p@ c #B3C2C9", "q@ c #B5C4CA", "r@ c #B8C6CA", "s@ c #C2CECF", "t@ c #D7E1DD", "u@ c #E8F0E8", "v@ c #F6FAEF", "w@ c #FBFDF3", "x@ c #FCFDF3", "y@ c #FAFCF0", "z@ c #F2F7EC", "A@ c #E4E9E2", "B@ c #D5DADA", "C@ c #C8CCCE", "D@ c #C4C8CD", "E@ c #C1C5CB", "F@ c #BDC2CB", "G@ c #BCC1CA", "H@ c #BDC3CA", "I@ c #BDC2C9", "J@ c #B9C0C8", "K@ c #B4BDC5", "L@ c #B0BAC4", "M@ c #B0B8C6", "N@ c #ABB4C4", "O@ c #A7B1C5", "P@ c #A5B1C6", "Q@ c #A6B0C4", "R@ c #A4AFC2", "S@ c #9FAFC6", "T@ c #9AAEC7", "U@ c #99ADC7", "V@ c #98AAC6", "W@ c #97A8C5", "X@ c #97A8C4", "Y@ c #95A7C4", "Z@ c #90A5C1", "`@ c #87A2C1", " # c #83A0C1", ".# c #82A0C1", "+# c #809EC2", "@# c #A9B8CB", "## c #ABBBCD", "$# c #AEBECF", "%# c #B0BFD2", "&# c #B2C2D3", "*# c #B6C5D0", "=# c #B8C6D0", "-# c #C8D5DE", ";# c #DDEAE8", "># c #F4FAF1", ",# c #FEFEF9", "'# c #FEFEFD", ")# c #FFFEFE", "!# c #FEFEFC", "~# c #FEFDF5", "{# c #F5F8EC", "]# c #E3E6DF", "^# c #CED3D4", "/# c #C7C9CD", "(# c #C5C7CC", "_# c #C3C8CC", ":# c #C3C7CB", "<# c #C0C4CC", "[# c #B9C1CA", "}# c #B7BFC8", "|# c #B5BCC8", "1# c #ABB7CB", "2# c #A9B6CA", "3# c #AAB5C9", "4# c #A8B4CA", "5# c #A7B3C8", "6# c #A6B2CA", "7# c #A4B0C8", "8# c #9FAFC7", "9# c #9BAFC8", "0# c #98ADC6", "a# c #97ABC5", "b# c #97AAC4", "c# c #96A9C4", "d# c #95A8C2", "e# c #92A3C2", "f# c #8BA0C2", "g# c #88A1C2", "h# c #869FC2", "i# c #ABB6D1", "j# c #ACB8D2", "k# c #AFBDD3", "l# c #B0C0D5", "m# c #B4C3D6", "n# c #B8C6D4", "o# c #BCC8D6", "p# c #D1DCE6", "q# c #EAF2EF", "r# c #FBFDF6", "s# c #FEFEFE", "t# c #FFFFFF", "u# c #FEFEFB", "v# c #FCFCF0", "w# c #EAEDE4", "x# c #D5D8D8", "y# c #BCC2CD", "z# c #B7BECF", "A# c #B1BBD0", "B# c #AEBAD1", "C# c #ABB9D0", "D# c #A7B8CF", "E# c #A4B7CE", "F# c #A3B5CD", "G# c #A3B4CD", "H# c #A2B4CC", "I# c #A2B3CB", "J# c #A0B2CA", "K# c #A0B1C9", "L# c #A0B0C9", "M# c #A1B0C9", "N# c #9EB0C8", "O# c #9AAFC7", "P# c #99AEC6", "Q# c #9BADC6", "R# c #97ACC4", "S# c #95ABC2", "T# c #92A7C2", "U# c #8FA6C2", "V# c #8EA4C2", "W# c #ABB9D1", "X# c #ACBAD2", "Y# c #AFBCD3", "Z# c #B2C1D5", "`# c #B4C4D6", " $ c #B8C7D4", ".$ c #C2CCD7", "+$ c #D7E0E5", "@$ c #EDF5EF", "#$ c #FCFEF9", "$$ c #FAFCF6", "%$ c #E6EEEC", "&$ c #D1D9E2", "*$ c #C1C8D4", "=$ c #BEC5D3", "-$ c #BAC2D4", ";$ c #B6C0D5", ">$ c #B1BCD5", ",$ c #A9BAD0", "'$ c #A8B9D0", ")$ c #A6B7CF", "!$ c #A4B3CE", "~$ c #A0B1CD", "{$ c #A1B0CD", "]$ c #A0B0CC", "^$ c #9FAECB", "/$ c #9FADCA", "($ c #9DADC9", "_$ c #9AABC9", ":$ c #9CAAC8", "<$ c #9BAAC7", "[$ c #9AABC7", "}$ c #9AAAC7", "|$ c #97AAC5", "1$ c #96ABC4", "2$ c #96AAC4", "3$ c #92A6C2", "4$ c #90A4C2", "5$ c #8FA4C2", "6$ c #8EA2C2", "7$ c #AAB9D1", "8$ c #ADBBD3", "9$ c #B1BED4", "0$ c #BBC7D4", "a$ c #C1C9D7", "b$ c #D4DDE6", "c$ c #E9F2EF", "d$ c #FBFDF7", "e$ c #F7FCF4", "f$ c #E2EBEC", "g$ c #CED6E4", "h$ c #BCC6D7", "i$ c #B5C4D7", "j$ c #B4C2D6", "k$ c #B5C0D5", "l$ c #AEBCD3", "m$ c #ABBAD1", "n$ c #A9B9D0", "o$ c #ABB8D1", "p$ c #A8B7CF", "q$ c #A4B5CD", "r$ c #A3B3CD", "s$ c #A1B1CC", "t$ c #9FB1CB", "u$ c #A1AFCA", "v$ c #9EAECA", "w$ c #9EAEC9", "x$ c #9DADC8", "y$ c #9BABC8", "z$ c #9BACC7", "A$ c #97A9C5", "B$ c #97A7C4", "C$ c #96A7C4", "D$ c #95A6C2", "E$ c #90A0C2", "F$ c #8FA1C2", "G$ c #8D9EC2", "H$ c #A7B6D1", "I$ c #ABB8D2", "J$ c #AEBAD3", "K$ c #AFBCD4", "L$ c #B1C0D6", "M$ c #B7C4D4", "N$ c #B9C6D5", "O$ c #C7D3E1", "P$ c #DCE7EB", "Q$ c #F2F9F2", "R$ c #FDFEFB", "S$ c #FCFEF8", "T$ c #EEF7F1", "U$ c #D8E4E9", "V$ c #C2D0DF", "W$ c #B6C5D7", "X$ c #B5C3D7", "Y$ c #B4C1D5", "Z$ c #B4BFD5", "`$ c #AFBAD4", " % c #A8B7D0", ".% c #A6B6CE", "+% c #A1B2CC", "@% c #A1B2CB", "#% c #A5B2CB", "$% c #A6B1CB", "%% c #A6B0CB", "&% c #A4AFCA", "*% c #A1AEC8", "=% c #A0AEC8", "-% c #9BAEC7", ";% c #97ABC4", ">% c #96AAC2", ",% c #8FA3C2", "'% c #8EA0C2", ")% c #ADB9D3", "!% c #AEBBD3", "~% c #B1BFD6", "{% c #B8C5D4", "]% c #BECAD9", "^% c #D0DCE6", "/% c #E2EEED", "(% c #F4FAF3", "_% c #FCFDF7", ":% c #FDFEF9", "<% c #F4F9F2", "[% c #E4EBEC", "}% c #D3DAE6", "|% c #C0C9D9", "1% c #BBC4D7", "2% c #B7C3D6", "3% c #B6C1D5", "4% c #B3BED5", "5% c #B0BBD5", "6% c #B0BAD4", "7% c #A5B6CE", "8% c #A5B5CD", "9% c #A1B3CC", "0% c #A0B1CB", "a% c #9FAFCA", "b% c #A0AFCA", "c% c #9FAEC9", "d% c #9AACC7", "e% c #99ADC6", "f% c #9AADC6", "g% c #9AABC5", "h% c #9AACC5", "i% c #99ACC4", "j% c #97AAC2", "k% c #91A5C2", "l% c #8FA2C2", "m% c #8DA0C2", "n% c #ADBAD3", "o% c #B2BCD6", "p% c #B5BFD5", "q% c #B7C2D6", "r% c #B9C3D7", "s% c #BCC6D5", "t% c #BCC8D5", "u% c #C2CEDD", "v% c #CFDDE6", "w% c #DCE7EA", "x% c #E5F0EE", "y% c #E8F3EF", "z% c #E6F1EE", "A% c #E0E8EA", "B% c #D2DCE7", "C% c #C2CDDD", "D% c #BDC5D7", "E% c #B9C2D6", "F% c #B7C1D5", "G% c #B3BDD6", "H% c #B1BBD5", "I% c #B1BBD4", "J% c #AFBBD4", "K% c #A8B7CE", "L% c #AAB6CE", "M% c #A9B5CE", "N% c #A6B3CD", "O% c #A3B3CB", "P% c #A1B0CA", "Q% c #9FB0CA", "R% c #9DB0C9", "S% c #9CAFC8", "T% c #9AADC7", "U% c #98ACC5", "V% c #98AAC5", "W% c #98ABC5", "X% c #95A9C2", "Y% c #92A5C2", "Z% c #92A4C3", "`% c #8FA3C3", " & c #AEBDD3", ".& c #B0BFD4", "+& c #B1C1D5", "@& c #B2C3D7", "#& c #B5C5D6", "$& c #B9C7D5", "%& c #BFCDDA", "&& c #C8D6E2", "*& c #CDDBE2", "=& c #CCD7D9", "-& c #C5D2D3", ";& c #BCC6CB", ">& c #B3BEC3", ",& c #AFBBC4", "'& c #B1BECC", ")& c #B3BFCF", "!& c #B4BFD1", "~& c #B4C1D3", "{& c #B1BFD4", "]& c #B1BED3", "^& c #AFBDD2", "/& c #ADBCD2", "(& c #ACBAD1", "_& c #A9B8CF", ":& c #A9B6CE", "<& c #A8B4CD", "[& c #A7B3CD", "}& c #A5B2CC", "|& c #A2B1CA", "1& c #9FB1CA", "2& c #9DAFC9", "3& c #9BAEC8", "4& c #9AACC8", "5& c #9AACC6", "6& c #9CACC6", "7& c #9BACC5", "8& c #9DACC5", "9& c #9FACC4", "0& c #9EACC3", "a& c #9AA8C4", "b& c #95A6C3", "c& c #94A3C5", "d& c #A8BAD0", "e& c #AABAD0", "f& c #ABBBD1", "g& c #ADBBD2", "h& c #AEBCCE", "i& c #A4ADB3", "j& c #989B94", "k& c #908E7D", "l& c #89826B", "m& c #80785C", "n& c #7B7253", "o& c #786E4D", "p& c #756A4A", "q& c #73674C", "r& c #6F654D", "s& c #6E654F", "t& c #6E6652", "u& c #706A59", "v& c #6F6959", "w& c #6B6457", "x& c #6A6659", "y& c #71736D", "z& c #7A7F80", "A& c #878F96", "B& c #9BA8BB", "C& c #A4B4CC", "D& c #A7B4CD", "E& c #A5B3CC", "F& c #A4B2CB", "G& c #9FB0C9", "H& c #9DAEC8", "I& c #9FB0C7", "J& c #A4B3C8", "K& c #AAB6C9", "L& c #ADB7CA", "M& c #AFB7CA", "N& c #AFB7C9", "O& c #ACB5C7", "P& c #A6B0C8", "Q& c #A1ACC6", "R& c #9FABC5", "S& c #99A8C6", "T& c #9EA9B6", "U& c #7E8078", "V& c #706751", "W& c #6B6047", "X& c #6A6047", "Y& c #6B6147", "Z& c #685E43", "`& c #615A3F", " * c #5F583D", ".* c #5F573D", "+* c #60573D", "@* c #615A41", "#* c #665C44", "$* c #6A5E44", "%* c #6B5E43", "&* c #685C45", "** c #665B45", "=* c #655B43", "-* c #665943", ";* c #635841", ">* c #615642", ",* c #5C523F", "'* c #564D3C", ")* c #514C3D", "!* c #5B5B52", "~* c #6F7072", "{* c #7E878F", "]* c #9BAAC0", "^* c #A1B1CA", "/* c #A7B5CB", "(* c #A9B5CA", "_* c #ACB6CB", ":* c #AFB7CB", "<* c #B2B9CB", "[* c #B1B8CA", "}* c #AEB6C9", "|* c #A6B1C6", "1* c #A3AFC5", "2* c #97A9C4", "3* c #92A3C5", "4* c #9AA6B4", "5* c #6C6D69", "6* c #585345", "7* c #625844", "8* c #665B43", "9* c #625940", "0* c #625941", "a* c #5B543D", "b* c #574F3B", "c* c #59513C", "d* c #5D533C", "e* c #564E3A", "f* c #5B513A", "g* c #5A513A", "h* c #5D533D", "i* c #5E5440", "j* c #5F5844", "k* c #645E49", "l* c #625C47", "m* c #605A47", "n* c #5E5845", "o* c #5C5543", "p* c #5D5542", "q* c #5B5543", "r* c #565241", "s* c #504D3F", "t* c #4D4A3E", "u* c #58584F", "v* c #7C8186", "w* c #7F868C", "x* c #7F848B", "y* c #7E8489", "z* c #798185", "A* c #838C95", "B* c #8E98AA", "C* c #9BA6BE", "D* c #A0ACC5", "E* c #9DABC4", "F* c #9CABC3", "G* c #97A9C3", "H* c #96A6C4", "I* c #94A5C3", "J* c #90A2C4", "K* c #A9B5CD", "L* c #828588", "M* c #4F4D42", "N* c #4B483D", "O* c #5C5141", "P* c #5D5340", "Q* c #5A513C", "R* c #5A503A", "S* c #5C513A", "T* c #5C523A", "U* c #574F3A", "V* c #5A533E", "W* c #5F5943", "X* c #645F48", "Y* c #6A6550", "Z* c #6B6755", "`* c #6C6A59", " = c #6E6E5C", ".= c #6E6E5D", "+= c #6B6B5A", "@= c #696958", "#= c #656453", "$= c #636253", "%= c #5F5F50", "&= c #5D5C4E", "*= c #58574A", "== c #56564A", "-= c #4F4F43", ";= c #4C4C41", ">= c #44453B", ",= c #414239", "'= c #3D3F37", ")= c #3C3C33", "!= c #35362E", "~= c #31322C", "{= c #2B2C27", "]= c #2A2B25", "^= c #282923", "/= c #2B2D27", "(= c #3F423F", "_= c #505659", ":= c #656D76", "<= c #727D8F", "[= c #8594AD", "}= c #93A4C1", "|= c #90A4C3", "1= c #8FA2C4", "2= c #686A66", "3= c #454137", "4= c #444036", "5= c #504A3C", "6= c #564D3B", "7= c #594D39", "8= c #564C38", "9= c #5F5742", "0= c #67614B", "a= c #686451", "b= c #676654", "c= c #686756", "d= c #696857", "e= c #636353", "f= c #636354", "g= c #5B5B4D", "h= c #59584B", "i= c #565649", "j= c #555548", "k= c #4E4F43", "l= c #494A3F", "m= c #49493E", "n= c #47483D", "o= c #48483D", "p= c #49483D", "q= c #45453B", "r= c #444339", "s= c #414137", "t= c #3C3D35", "u= c #3A3B34", "v= c #363832", "w= c #383831", "x= c #32342F", "y= c #2A2D28", "z= c #2D2E27", "A= c #2C2D27", "B= c #2C2D26", "C= c #2C2D25", "D= c #21221E", "E= c #262622", "F= c #2A2B29", "G= c #373C41", "H= c #4D5460", "I= c #3C3A31", "J= c #3D3A30", "K= c #4B4534", "L= c #564B37", "M= c #544A37", "N= c #504B3C", "O= c #4B4B3E", "P= c #4D4D41", "Q= c #4F4F44", "R= c #4D4D42", "S= c #4E4F44", "T= c #505044", "U= c #505045", "V= c #505145", "W= c #515246", "X= c #525346", "Y= c #525348", "Z= c #4D4E42", "`= c #46463B", " - c #3F3F36", ".- c #3F3F35", "+- c #383830", "@- c #393930", "#- c #34342C", "$- c #313029", "%- c #2E2E27", "&- c #2B2C26", "*- c #2D2D27", "=- c #282822", "-- c #23231E", ";- c #1F1F1A", ">- c #252420", ",- c #39362F", "'- c #33312C", ")- c #292A27", "!- c #2E2D2B", "~- c #2C2C29", "{- c #242322", "]- c #2C2C2A", "^- c #3B392E", "/- c #494232", "(- c #514A39", "_- c #4E4C3D", ":- c #515143", "<- c #545446", "[- c #525244", "}- c #535346", "|- c #525246", "1- c #535246", "2- c #515145", "3- c #504F43", "4- c #49483E", "5- c #43433A", "6- c #424239", "7- c #3A3A32", "8- c #37372F", "9- c #32322B", "0- c #303129", "a- c #2E3027", "b- c #2F3027", "c- c #2D2E26", "d- c #292A22", "e- c #2A2A22", "f- c #282821", "g- c #23241D", "h- c #20201A", "i- c #1D1D19", "j- c #1B1B17", "k- c #1A1A16", "l- c #181814", "m- c #171813", "n- c #141411", "o- c #1F1D19", "p- c #3C3932", "q- c #373532", "r- c #2C2B29", "s- c #32312E", "t- c #2F2F2D", "u- c #252523", "v- c #4A473A", "w- c #535245", "x- c #575649", "y- c #58584A", "z- c #59584A", "A- c #3C3D33", "B- c #3D3D34", "C- c #404036", "D- c #3E3E35", "E- c #3C3C34", "F- c #3B3B33", "G- c #3A3B32", "H- c #393A31", "I- c #36362F", "J- c #36372F", "K- c #36372E", "L- c #34352D", "M- c #32332B", "N- c #2B2C24", "O- c #272820", "P- c #26261F", "Q- c #24241D", "R- c #22211B", "S- c #201F1B", "T- c #20201B", "U- c #1E1E1A", "V- c #1C1C18", "W- c #191916", "X- c #161613", "Y- c #12120F", "Z- c #10100D", "`- c #1B1B16", " ; c #31302A", ".; c #2A2927", "+; c #262523", "@; c #242321", "#; c #1F1D1A", "$; c #4E4C3F", "%; c #525042", "&; c #565447", "*; c #514F43", "=; c #585749", "-; c #59594B", ";; c #545347", ">; c #3B3C32", ",; c #3B3C33", "'; c #4E4E42", "); c #4D4E41", "!; c #4E4D41", "~; c #59584C", "{; c #616055", "]; c #58584D", "^; c #434452", "/; c #363A58", "(; c #393B3C", "_; c #282825", ":; c #272720", "<; c #272620", "[; c #25241E", "}; c #21211C", "|; c #1E1D19", "1; c #1B1B18", "2; c #171714", "3; c #131310", "4; c #13130F", "5; c #1F201B", "6; c #41423C", "7; c #3F3F3B", "8; c #353532", "9; c #3B3A36", "0; c #30302E", "a; c #252524", "b; c #2E2E2C", "c; c #5E5C4E", "d; c #5F5E50", "e; c #646353", "f; c #5F5E4F", "g; c #47473C", "h; c #48483C", "i; c #47463B", "j; c #424237", "k; c #434338", "l; c #414136", "m; c #3D3E34", "n; c #545346", "o; c #636252", "p; c #626151", "q; c #626051", "r; c #615F50", "s; c #605E50", "t; c #5E5D4F", "u; c #505048", "v; c #333459", "w; c #373852", "x; c #2A2A24", "y; c #272722", "z; c #2B2B24", "A; c #25251F", "B; c #292922", "C; c #1E1E19", "D; c #1F1F19", "E; c #22221C", "F; c #21211B", "G; c #1E1E18", "H; c #3F3E39", "I; c #3D3B33", "J; c #2F2F2C", "K; c #1A1A18", "L; c #151412", "M; c #2C2B28", "N; c #5A594C", "O; c #5F5D4E", "P; c #616051", "Q; c #5C5C4D", "R; c #48473B", "S; c #4C4B3F", "T; c #4D4D3F", "U; c #4B4A3E", "V; c #49493D", "W; c #4B4B42", "X; c #767669", "Y; c #7E7D6C", "Z; c #7E7C6C", "`; c #7B7A6A", " > c #706F5F", ".> c #656455", "+> c #5A5A4D", "@> c #3D3E53", "#> c #323256", "$> c #323234", "%> c #2C2C24", "&> c #35352C", "*> c #37382E", "=> c #323229", "-> c #3A3A2F", ";> c #323228", ">> c #2B2D23", ",> c #2F3025", "'> c #2C2D24", ")> c #282921", "!> c #2D2E24", "~> c #2C2C23", "{> c #1C1C19", "]> c #3C3A35", "^> c #3B3731", "/> c #381914", "(> c #351613", "_> c #351312", ":> c #1C1B1B", "<> c #121211", "[> c #59574B", "}> c #514E41", "|> c #49483B", "1> c #525043", "2> c #5B5A4C", "3> c #444338", "4> c #48483B", "5> c #464639", "6> c #4A493C", "7> c #424138", "8> c #3B3B32", "9> c #4B4A3F", "0> c #676657", "a> c #6A6959", "b> c #6E6D5D", "c> c #737262", "d> c #676763", "e> c #444566", "f> c #34355E", "g> c #2F303C", "h> c #262623", "i> c #25251E", "j> c #23221C", "k> c #222123", "l> c #212026", "m> c #282731", "n> c #252430", "o> c #242330", "p> c #211F2F", "q> c #1D1B2B", "r> c #1B1925", "s> c #1A1726", "t> c #161423", "u> c #171524", "v> c #161424", "w> c #0F0F20", "x> c #161425", "y> c #1B1825", "z> c #20141C", "A> c #1E1419", "B> c #1D1218", "C> c #15141D", "D> c #08080D", "E> c #555447", "F> c #565448", "G> c #5A594B", "H> c #39392F", "I> c #454539", "J> c #49493C", "K> c #3E3D33", "L> c #313129", "M> c #31312A", "N> c #626152", "O> c #616052", "P> c #5D5D52", "Q> c #41424B", "R> c #31333E", "S> c #303037", "T> c #272726", "U> c #252521", "V> c #242421", "W> c #232220", "X> c #21201B", "Y> c #1C1C1A", "Z> c #1B1B1A", "`> c #201F22", " , c #1D1C20", "., c #1A191C", "+, c #171619", "@, c #131215", "#, c #15141A", "$, c #0F0F12", "%, c #121117", "&, c #121116", "*, c #0B0B0A", "=, c #0A0A09", "-, c #090908", ";, c #080808", ">, c #0B0A0B", ",, c #131212", "', c #4E4C3E", "), c #514F42", "!, c #504E40", "~, c #565446", "{, c #555345", "], c #525245", "^, c #32332A", "/, c #3A3B2E", "(, c #3B3C2F", "_, c #33322A", ":, c #38382F", "<, c #53544C", "[, c #464751", "}, c #363753", "|, c #323240", "1, c #2A2925", "2, c #252520", "3, c #242423", "4, c #232222", "5, c #201F1A", "6, c #222022", "7, c #1F1F1F", "8, c #1F1E1F", "9, c #1A1918", "0, c #191917", "a, c #161614", "b, c #131312", "c, c #11110F", "d, c #0F0F0E", "e, c #0E0E0F", "f, c #0F0F0D", "g, c #11110E", "h, c #131210", "i, c #292724", "j, c #2E2926", "k, c #282622", "l, c #312F2B", "m, c #312E29", "n, c #2D2A24", "o, c #302E2B", "p, c #8E836C", "q, c #8F846D", "r, c #8E846D", "s, c #8F856E", "t, c #877E69", "u, c #827864", "v, c #7E7460", "w, c #7F7561", "x, c #5E5B54", "y, c #343541", "z, c #2E2E34", "A, c #2B2B31", "B, c #2B2B32", "C, c #32323E", "D, c #393A47", "E, c #333455", "F, c #33344F", "G, c #313137", "H, c #282823", "I, c #1F1E1A", "J, c #1D1C19", "K, c #1C1B18", "L, c #1B1B19", "M, c #292726", "N, c #38372E", "O, c #514A3A", "P, c #4A4439", "Q, c #534C3A", "R, c #524B3A", "S, c #474038", "T, c #504937", "U, c #463F39", "V, c #474037", "W, c #4B4438", "X, c #524B3D", "Y, c #61594C", "Z, c #5F564C", "`, c #5A5147", " ' c #5A5249", ".' c #524B42", "+' c #4D463D", "@' c #504940", "#' c #958A71", "$' c #968B72", "%' c #978B73", "&' c #988C73", "*' c #978C73", "=' c #988C74", "-' c #605B4B", ";' c #2A2A23", ">' c #535349", ",' c #48484C", "'' c #37394E", ")' c #2B2B41", "!' c #272727", "~' c #23221F", "{' c #474339", "]' c #7A705E", "^' c #7E7760", "/' c #6A6856", "(' c #908467", "_' c #857865", ":' c #8A7D65", "<' c #908364", "[' c #827560", "}' c #8D7F62", "|' c #8A7B62", "1' c #847560", "2' c #897A60", "3' c #887960", "4' c #847562", "5' c #847461", "6' c #827360", "7' c #81725F", "8' c #82725F", "9' c #95886C", "0' c #95896D", "a' c #958A6E", "b' c #968A6F", "c' c #978A71", "d' c #978B71", "e' c #978B72", "f' c #988B73", "g' c #827863", "h' c #625D4D", "i' c #434237", "j' c #3C3C32", "k' c #5B5B4C", "l' c #4F4F42", "m' c #4D4C40", "n' c #3F3E34", "o' c #38383C", "p' c #444450", "q' c #3E3C4A", "r' c #4E4B48", "s' c #736B59", "t' c #94876B", "u' c #988B6E", "v' c #998C6E", "w' c #988A6B", "x' c #978969", "y' c #948765", "z' c #908360", "A' c #8F815F", "B' c #8D7F5F", "C' c #8A7B61", "D' c #897A61", "E' c #897960", "F' c #857662", "G' c #837562", "H' c #81735F", "I' c #817260", "J' c #958765", "K' c #958766", "L' c #958867", "M' c #968867", "N' c #968968", "O' c #978968", "P' c #97896A", "Q' c #95886A", "R' c #8F8468", "S' c #908468", "T' c #766D57", "U' c #6F6B58", "V' c #5B5848", "W' c #646252", "X' c #656454", "Y' c #84785C", "Z' c #8C7F60", "`' c #7E775E", " ) c #948768", ".) c #918970", "+) c #9B8F71", "@) c #9D9071", "#) c #9B8D6D", "$) c #998B6B", "%) c #998C6B", "&) c #9C8F6F", "*) c #958767", "=) c #8C7D63", "-) c #8A7A61", ";) c #867661", ">) c #837461", ",) c #807161", "') c #938666", ")) c #948769", "!) c #95886B", "~) c #94886C", "{) c #95896E", "]) c #958A6F", "^) c #958A70", "/) c #897F67", "() c #766D59", "_) c #6A6251", ":) c #635F4E", "<) c #7B7664", "[) c #645F4E", "}) c #625E4E", "|) c #4E4838", "1) c #5E5D4E", "2) c #696554", "3) c #6D6956", "4) c #777461", "5) c #7B7660", "6) c #837D69", "7) c #726E5C", "8) c #6B6551", "9) c #847759", "0) c #86795A", "a) c #908361", "b) c #908261", "c) c #908260", "d) c #918361", "e) c #938565", "f) c #95876E", "g) c #96886F", "h) c #8E8066", "i) c #867761", "j) c #93886D", "k) c #94886E", "l) c #94896F", "m) c #94886F", "n) c #7C735E", "o) c #706855", "p) c #6D6552", "q) c #6D6550", "r) c #655E4A", "s) c #665F4B", "t) c #7D755B", "u) c #847B60", "v) c #827A5F", "w) c #867D62", "x) c #7A725A", "y) c #7A735C", "z) c #8C846B", "A) c #8A7F63", "B) c #72684E", "C) c #6E644B", "D) c #6D634B", "E) c #6D634A", "F) c #71664C", "G) c #635942", "H) c #645A43", "I) c #6F644C", "J) c #665B48", "K) c #5D5341", "L) c #716652", "M) c #796E5B", "N) c #63594A", "O) c #625647", "P) c #5F5344", "Q) c #3D362C", "R) c #39332A", "S) c #4C4439", "T) c #665A4B", "U) c #716454", "V) c #665B4C", "W) c #594F44", "X) c #65594D", "Y) c #92866C", "Z) c #93876D", "`) c #93886E", " ! c #92876D", ".! c #716955", "+! c #786F5A", "@! c #867B64", "#! c #92856A", "$! c #948766", "%! c #948665", "&! c #938665", "*! c #938564", "=! c #9D9070", "-! c #9B8E6E", ";! c #928463", ">! c #918362", ",! c #8F805F", "'! c #8C7D61", ")! c #8B7C66", "!! c #908372", "~! c #8A7B69", "{! c #786A58", "]! c #91856B", "^! c #92876C", "/! c #93876A", "(! c #928564", "_! c #928563", ":! c #918462", "~ c #908268", ",~ c #93856B", "'~ c #877861", ")~ c #8E8072", "!~ c #928578", "~~ c #817364", "{~ c #877761", "]~ c #93846B", "^~ c #8C7E6C", "/~ c #827263", "(~ c #877869", "_~ c #978B7F", ":~ c #91836E", "<~ c #817363", "[~ c #867769", "}~ c #837466", "|~ c #847561", "1~ c #887967", "2~ c #908271", "3~ c #817264", "4~ c #88796B", "5~ c #94877A", "6~ c #857667", ". + @ # $ % % & * = - - - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 4 5 6 7 8 9 0 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 ( A B C D E F G H I J K L M N O P Q c R R S T ", "U h % V V k W X Y Z ` ...+.@.@.q #.; $.%.v &.*.=.-.;.-.>._ _ ,.'.).!.~.{.].^./.(._.:.<.[.}.|.1.", "2.3.4.5.6.7.8.9.0.a.b.c.d.e.e.f.+.g.h.i.j.k.u l.m.n.o.o.p._ q.r.s.t.~.K u.v.w.x.x.y.z.A.B.C.D.E.", "F.% G.H.I.J.K.L.M.N.O.P.P.Q.R.S.T.U.@.r V.W.X.Y.Y.Z.`. +p..+++@+++#+u.$+%+&+*+=+(.-+;+>+,+'+)+!+", "~+{+G.W ]+^+/+(+_+:+<+[+}+|+1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+j+u.k+l+m+n+o+p+q+r+s+t+u+v+", "F.$ V w+Z x+y+z+A+B+C+D+E+F+G+H+I+J+K+L+M+N+O+O+K+P+Q+R+S+T+U+V+W+X+Y+Z+`+k+ @.@+@@@#@$@%@&@&@*@", "=@-@J.;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@P+3@4@5@6@6@7@8@9@0@a@b@c@d@%+e@f@g@h@i@j@k@&@&@l@", "m@n@r o@p@q@r@s@t@u@v@w@x@y@z@A@B@C@D@1@E@L+F@G@H@K+I@J@K@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#", "@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#W.1#2#3#4#5#6#7#7#8#9#T@T@0#a#b#c#d#e#f#g#h#", "i#j#k#l#m#n#o#p#q#r#s#s#t#s#u#v#w#x#/#(#E@y#z#A#B#C#D#E#F#G#H#H#I#J#J#K#L#M#N#O#P#Q#R#S#T#U#U#V#", "W#X#Y#Z#`# $.$+$@$#$t#s#t#t#s#$$%$&$*$=$-$;$>$X#,$'$)$!$~${$]$^$/$($_$:$<$[$}$V@|$1$2$d#3$4$5$6$", "7$8$9$Z#m#0$a$b$c$d$s#s#t#s#s#e$f$g$h$i$j$k$l$m$,$n$o$p$q$r$s$t$u$v$w$x$y$z$[$V@A$B$C$D$e#E$F$G$", "H$I$J$K$L$M$N$O$P$Q$R$s#t#s#S$T$U$V$W$X$Y$Z$>$`$W# %.%q$G#H#+%@%#%$%%%&%*%=%-%0#|$|$;%>%3$,%,%'%", "o$)%!%K$~%j${%]%^%/%(%_%:%r#<%[%}%|%1%2%3%4%5%6%J$)%o$7%8%q$9%0%a%b%c%x$z$d%e%f%g%h%i%j%k%l%l%m%", "n%5%o%p%q%r%s%t%u%v%w%x%y%z%A%B%C%D%1%E%F%G%H%I%J%J$o$K%L%M%N%O%P%Q%R%S%T@T%e%U%V%W%1$X%Y%Z%Z%`%", "n$m$8$ &.&+&@&#&$&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&:&<&[&}&|&1&2&3&4&d%5&6&7&8&9&0&a&B$b&c&", "d&e&f&g&!%.&h&i&j&k&l&m&n&o&p&q&r&r&s&t&u&v&w&x&y&z&A&B&C&D&E&F&P%Q%G&H&N#I&J&K&L&M&N&O&P&Q&R&S&", "'$e&8$!%T&U&V&W&X&Y&Z&`& *.*+*@*#*$*%*&***=*-*;*>*,*'*)*!*~*{*]*^*#%/*(*_*:*<*[*}*|*1*9&X@2*X@3*", ")%'$4*5*6*7*8*9*0*a*b*c*d*b*e*f*g*h*i*j*k*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z*A*B*C*D*E*F*G*b&H*I*J*", "K*L*M*N*O*P*Q*R*S*T*f*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=&=*===-=;=>=,='=)=!=~={=]=^=/=(=_=:=<=[=}=|=1=", "2=3=4=5=6=7=8=9=0=a=b=c=d=c=e=f=g=g=h=i=j=k=l=m=n=o=p=q=r=s=t=u=v=w=x=~=y=z=A=B=C=C=B=D=E=F=G=H=", "I=J=K=L=M=N=O=P=Q=R=S=T=U=T=T=V=Q=V=W=X=Y=R=Z=-=;=;=`=`= -.-+-@-#-$-%-&-*-=---;->-,-'-)-!-~-{-]-", "^-/-(-_-:-<-[-}-}-|-1-2-|-P=3-p=4- -5-6-7-8-8-!=9-0-a-b-c-d-e-f-g-h-i-j-k-l-m-n-o-p-q-r-s-t-u-r-", "v-w-x-y-z-&=y-)=A-B-.-C-C- -D-)=E-F-G-H-I-J-K-L-M-0-c-N-O-P-Q-R-S-T-U-V-W-X-Y-Z-`- ;.;+;.;@;#;@;", "$;%;&;*;=;-;;;)=>;,;,;A-A-,;,;G-,;';';);!;~;{;];^;/;(;_;:;<;[;};|;1;W-2;n-3;n-4;5;6;7;8;9;0;a;b;", "h==;c;d;e;e;f;o=g;h;i;j;k;l;.-m;n;o;p;q;r;s;t;u;v;w;x;y;z;P-[;A;B;--T-C;D;E;F;G;;-H;I;$-J;K;L;M;", "N;=;O;&=r;P;Q;R;S;T;U;V;T;O=W;X;Y;Z;`; >.>&=+>@>#>$>P-A;%>&>*>=>->;>>>,>'>)>!>~>{>]>^>/>(>_>:><>", "[>i=}>|>1>2>*=3>4>4>R;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>j=G>x-<-H>I>J>4>J>K>L>%-#-M>N>O>P>Q>R>S>T>U>V>W>X>|;Y>Z>`> ,.,+,@,#,$,%,&,*,=,-,-,;,;,>,,,", "',),),!,~,{,],^,/,(,(,&>_,z;z;L>:,<,[,},|,1,P-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,q,r,q,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,i>Q-j>X>I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,`, '.'+'@'", "#'$'%'%'&'&'*'='='='-';':;P-P-T=j=j=>',''')'!'5,|;J,~'{']'^'/'('_':'<'['}'|'1'2'3'4'5'6'7'8'8'7'", "9'0'a'b'c'd'd'e'f'f'f'g'h'i'j'],k'l'9>m'n'o'p'q'r's't'u'v'v'w'x'y'z'A'B'C'D'2'E'F'G'G'6'H'7'H'I'", "y'J'J'K'K'L'M'N'O'O'x'P'Q'R'S'T'U'V'W'X'Y'Z'`'K' ).)+)@)#)$)%)#)&)#)*)=)-)2'2';)4'>)>)6'7'7'7',)", "') )))Q'!)~)0'{)])^)/)()_):)<)[)})|)[-1)2)3)4)5)6)7)8)9)0)a)b)c)d)e)f)g)h)2'i)4'5'>)5'6'7'7'I',)", "j)j)k)l)m)m)l)l)m)/)n)o)p)q)r)s)t)u)v)w)x)y)z)A)B)C)D)E)E)F)G)H)I)J)K)L)M)N)O)P)Q)R)S)T)U)V)W)X)", "Y)Z)Z)j)`)k)k) !.!+!@!#!$!%!%!%!%!&!*!*!&!=!-!;!>!a)a)b)c)A',!'!C'D'2'2')!!!~!>){!>)5'6'I',),),)", "]!Y)Y)Y)^!Z)j)j)j)/!e)*!*!(!(!_!;!;!;!:!)>)5'6',)4!4!4!", "5!]!]!6!7!Y)Y)8!9!:!:!:!:!:!:!:!>!>!>!%!0!%!a)b)c)a!A'b!c!C'D'd!2'3'F'4'e!4'f!g!4'>)e!h!4!i!i!4!", "j!k!5!5!5!l!m!d)>!n!n!>!>!n!>!>!>!a)d)o!o!c)a!A'A',!p!C'-)D'2'2'q!F'4'4'e!r!s!!!t!e!e!u!i!v!v!i!", "w!x!x!y!z!c)c)c)A!A!d)d)d)a)d)b)c)c)d)&)*!A',!b!B!C'-)d!2'2'C!D!E!F!G!H!f!I!4'F!J!e!K!L!4!,)4!4!", "M!N!O!,!A'A'A'A'a!a!a!c)c)a!a!A'A'A'P!Q!,!p!1!C'-)2'2'2'2'R!S!T!4'U!U!4'V!G!J!W!X!Y!K!L!4!L!4!,)", "Z!-)-)`! ~.~|!+~,!,!,!,!,!,!,!b!|!p!@~#~C'-)D'-)2'2'2'$~%~&~4'4'r!e!4'e!e!4'J!*~=~Y!-~L!,)L!i!L!", "2'2'D'-)d!2'-)-)C';~;~`!;~;~C'-)-)2'>~,~-)2'2'2'3''~F't!H!4'>)>)>)>)>)>)>)e!K!)~!~Y!~~L!4!4!4!4!", "F'{~3'2'2'2'2'd!2'd!d!d!-)d!d!d!d!2'>~]~2'3''~;)4'4'r!^~T!r!>)>)5'>)5'>)e!K!/~(~_~Y!/~L!4!i!4!4!", "4'4'4'F'i){~q!3'2'2'2'2'2'2'2'2'3'3'R!:~F'4'4'4'4'e!4'H!4'e!e!e!e!e!e!K!K!<~<~[~_~}~<~L!i!i!i!i!", "U!U!U!|~4'4'4'4'4'4'F'F'F'F'F'4'4'4'1~2~4'U!>)>)4'U!4'F!>)>)U!>)r!e!K!3~-~3~3~4~5~6~3~L!4!4!4!4!"}; searchandrescue_1.5.0/sar/icons/SearchAndRescue4.xpm0000644000175000017500000004672010104532745021465 0ustar jessejesse/* XPM */ static char * SearchAndRescue4_xpm[] = { "48 48 941 2", " c None", ". c #C9DAF7", "+ c #C9DAF8", "@ c #C8D9F8", "# c #C4D9F6", "$ c #C6D8F7", "% c #C5D6F7", "& c #C6D6F7", "* c #C1D6F6", "= c #C0D5F6", "- c #BFD5F5", "; c #BDD5F5", "> c #BED5F6", ", c #C4D6F6", "' c #C5D5F7", ") c #C5D7F7", "! c #C6D5F7", "~ c #C5D8F7", "{ c #C4D9F7", "] c #CDDAF8", "^ c #CDDBF8", "/ c #CEDAF7", "( c #D4DDF7", "_ c #D5DCF8", ": c #D6DDF7", "< c #D6DDF5", "[ c #D5DDF3", "} c #D5DDF4", "| c #D5DDF0", "1 c #D4DCF1", "2 c #D4DBF4", "3 c #D3DBF0", "4 c #D4DBEE", "5 c #D4DBED", "6 c #C5D7F6", "7 c #C5D6F6", "8 c #C1D5F6", "9 c #BCD5F5", "0 c #BDD4F6", "a c #BDD2F7", "b c #BDD1F7", "c c #BCD6F5", "d c #BDD6F5", "e c #C4DAF6", "f c #C6DAF8", "g c #CCDAF7", "h c #CCDAF8", "i c #CDDAF7", "j c #C6D9F7", "k c #CCDBF7", "l c #CFDBF8", "m c #D5DDF7", "n c #D5DCF6", "o c #D4DDF6", "p c #D5DCF7", "q c #D5DDF5", "r c #D4DCF5", "s c #D3DBF5", "t c #D4DBF3", "u c #D3DBED", "v c #D4DAED", "w c #D4DDEE", "x c #D3DFEE", "y c #C5D5F6", "z c #C0D6F6", "A c #C2D6F6", "B c #BDD3F6", "C c #BED2F7", "D c #BDD2F6", "E c #BCD5F4", "F c #C0D5F5", "G c #C5D8F6", "H c #C7DAF7", "I c #CBDAF7", "J c #CBDAF8", "K c #CADAF8", "L c #C8DAF7", "M c #CFDBF7", "N c #CCDAF6", "O c #D3DBF2", "P c #D3DBEF", "Q c #D3DBEC", "R c #D3DDEE", "S c #D3E0F2", "T c #C3D5F7", "U c #BED6F5", "V c #BDD1F6", "W c #BED1F7", "X c #BED3F6", "Y c #BFD6F6", "Z c #BFD6F5", "` c #BED5F5", " . c #C0D7F6", ".. c #C2D8F7", "+. c #C5D9F7", "@. c #C6D7F7", "#. c #C5DAF7", "$. c #D0DAF6", "%. c #D3DAF5", "&. c #D2DAF5", "*. c #D3DBF3", "=. c #D4DCEE", "-. c #D4DEEE", ";. c #D4DEF0", ">. c #D4DDEF", ",. c #BED4F6", "'. c #BDD4F5", "). c #BCD6F4", "!. c #C2D5F6", "~. c #C4D7F7", "{. c #C3D8F7", "]. c #C6DAF7", "^. c #CADAF7", "/. c #CEDBF8", "(. c #D2DBF6", "_. c #D3DBF4", ":. c #D4DAF5", "<. c #D4DBF5", "[. c #C4D6F7", "}. c #C0D6F5", "|. c #BDD5F6", "1. c #C4DAF7", "2. c #CED9F5", "3. c #D1DAF4", "4. c #D2DBF4", "5. c #C1D5F5", "6. c #BED6F6", "7. c #C5D9F6", "8. c #C7DAF6", "9. c #CAD9F6", "0. c #C7D8F6", "a. c #C7D8F7", "b. c #CAD8F6", "c. c #CCD9F6", "d. c #CFDAF5", "e. c #CDD9F6", "f. c #C3D7F7", "g. c #C4D8F7", "h. c #C4D8F6", "i. c #C3D7F6", "j. c #C3D5F6", "k. c #C7D9F7", "l. c #C9D9F7", "m. c #C2D8F6", "n. c #C4D7F5", "o. c #C6D8F6", "p. c #CBD8F5", "q. c #C3D6F6", "r. c #C1D7F6", "s. c #BFD5F6", "t. c #C1D4F6", "u. c #C4D6F5", "v. c #C3D7F5", "w. c #C4D8F5", "x. c #C6D8F5", "y. c #C6D6F6", "z. c #C7DAF8", "A. c #C3D5F4", "B. c #C4D5F5", "C. c #C3D5F5", "D. c #C3D8F5", "E. c #C6DAF6", "F. c #C3D9F7", "G. c #C4D7F6", "H. c #C2D8F5", "I. c #C4D9F8", "J. c #C3D9F6", "K. c #C4D4F5", "L. c #BFD4F6", "M. c #BDD3F7", "N. c #BED3F7", "O. c #C3D6F7", "P. c #C3D8F6", "Q. c #CFDCF7", "R. c #CDDCF7", "S. c #C5D9F8", "T. c #C5D8F8", "U. c #C2D6F5", "V. c #C3D9F5", "W. c #CEDBF7", "X. c #C2D7F6", "Y. c #BED4F5", "Z. c #C0D4F6", "`. c #C2D7F7", " + c #BCD4F5", ".+ c #BBD4F6", "++ c #BBD3F6", "@+ c #BCD3F6", "#+ c #B9D4F5", "$+ c #BCD4F6", "%+ c #BBD4F5", "&+ c #C0D5F7", "*+ c #C1D7F7", "=+ c #C0D7F5", "-+ c #C3D6F5", ";+ c #C1D6F5", ">+ c #C8D9F6", ",+ c #C5D9F5", "'+ c #C8DAF6", ")+ c #C9DAF6", "!+ c #CBD8F3", "~+ c #E3E7F5", "{+ c #C9D6F2", "]+ c #C8DBF6", "^+ c #C8DBF5", "/+ c #CADBF5", "(+ c #CBDCF5", "_+ c #CDDBF4", ":+ c #CEDCF5", "<+ c #D0DCF5", "[+ c #D0DDF6", "}+ c #D1DEF6", "|+ c #CAD1EC", "1+ c #EA3131", "2+ c #F03635", "3+ c #E54B50", "4+ c #C6D4F2", "5+ c #C0D5F3", "6+ c #BCCFED", "7+ c #B4C6E1", "8+ c #A3B5CD", "9+ c #7A879A", "0+ c #8493A6", "a+ c #B4C9E6", "b+ c #C1D8F7", "c+ c #CBDBF5", "d+ c #CCDBF5", "e+ c #CEDCF4", "f+ c #D0DCF4", "g+ c #CFDDF5", "h+ c #D2DCF5", "i+ c #C9DBF6", "j+ c #C7DBF6", "k+ c #E04B52", "l+ c #E4201D", "m+ c #E32520", "n+ c #D193A6", "o+ c #BFD7F8", "p+ c #C0D7F7", "q+ c #C0D4F2", "r+ c #B6C7E4", "s+ c #B0C1DC", "t+ c #A8B9D2", "u+ c #A0B1C8", "v+ c #92A2B8", "w+ c #808FA4", "x+ c #687384", "y+ c #4A515B", "z+ c #565E6C", "A+ c #8A95A8", "B+ c #B5C6E1", "C+ c #CEDEF6", "D+ c #C6D9F6", "E+ c #C0D6F4", "F+ c #BDD3F0", "G+ c #BACEEB", "H+ c #B5C7E4", "I+ c #AFC1DD", "J+ c #A9BAD4", "K+ c #A2B3CB", "L+ c #9CACC3", "M+ c #98A6BD", "N+ c #93A0B4", "O+ c #8B97AA", "P+ c #93A1B5", "Q+ c #A7B6CD", "R+ c #C8D9F3", "S+ c #CFDEF7", "T+ c #DD7F8B", "U+ c #D81716", "V+ c #D01615", "W+ c #D62C2E", "X+ c #CDD1EB", "Y+ c #C4D7F3", "Z+ c #C3D6F0", "`+ c #C2D3EB", " @ c #B6C6DE", ".@ c #AEC0D8", "+@ c #A4B4CB", "@@ c #8C99AB", "#@ c #76808E", "$@ c #555A62", "%@ c #5F6671", "&@ c #7C8187", "*@ c #858B96", "=@ c #95A4B7", "-@ c #8C9AAE", ";@ c #95A4BA", ">@ c #8B99AE", ",@ c #8592A6", "'@ c #818FA2", ")@ c #8894A9", "!@ c #8695AC", "~@ c #909EB7", "{@ c #8A99B2", "]@ c #8B99B2", "^@ c #9BABC2", "/@ c #9AAAC1", "(@ c #98A8BF", "_@ c #A6B6CF", ":@ c #A2B2CB", "<@ c #A0B2CB", "[@ c #BFD3F0", "}@ c #CEAFC5", "|@ c #CE1715", "1@ c #CD1715", "2@ c #D31C19", "3@ c #CD7986", "4@ c #C3DAF7", "5@ c #BCD2EF", "6@ c #94A6BD", "7@ c #8B9BB0", "8@ c #8D9DB2", "9@ c #8898AC", "0@ c #8D9BAF", "a@ c #8D9BB0", "b@ c #90A0B5", "c@ c #909FB6", "d@ c #92A3B8", "e@ c #97A9C0", "f@ c #9EAEC5", "g@ c #B494A1", "h@ c #CF696D", "i@ c #D5797C", "j@ c #E09599", "k@ c #C58586", "l@ c #AC878E", "m@ c #9D9CAA", "n@ c #7D8896", "o@ c #707B89", "p@ c #8B9BAF", "q@ c #9EB1C9", "r@ c #B1C7E3", "s@ c #BCD3F3", "t@ c #C1D8FA", "u@ c #BFD7FB", "v@ c #BED8FB", "w@ c #BED6FC", "x@ c #BED6F9", "y@ c #C0D8F7", "z@ c #BFD7F9", "A@ c #BED7FA", "B@ c #C0D9FB", "C@ c #BFD9FD", "D@ c #C2D5F7", "E@ c #CC3637", "F@ c #D72724", "G@ c #DE2722", "H@ c #E82E2C", "I@ c #C8C4E0", "J@ c #C1DAFA", "K@ c #C2D9FB", "L@ c #C1DAF9", "M@ c #C1DAF8", "N@ c #C1D9F7", "O@ c #C1D9F9", "P@ c #BFD9F9", "Q@ c #C1D9FA", "R@ c #C3DAF8", "S@ c #C4DCF7", "T@ c #C5DBF7", "U@ c #C4DAF8", "V@ c #CFBCD3", "W@ c #EA5C61", "X@ c #EB3434", "Y@ c #E13D3E", "Z@ c #C52F2E", "`@ c #D03938", " # c #CB7270", ".# c #6E5051", "+# c #F44B4B", "@# c #CBBCD1", "## c #B6CEE8", "$# c #9CADC4", "%# c #AEC2DC", "&# c #C2D9FA", "*# c #C3D9F9", "=# c #C4DAF5", "-# c #C3DAF5", ";# c #C5DAF5", "># c #C7DAF5", ",# c #C7DBF4", "'# c #C5DAFD", ")# c #C4DAFE", "!# c #C5D8FC", "~# c #EC565A", "{# c #F63532", "]# c #F63835", "^# c #F62A2B", "/# c #E56B76", "(# c #C5DBFA", "_# c #C5DBFC", ":# c #C6DCFB", "<# c #CBCEEA", "[# c #D8A4B7", "}# c #CCDDF9", "|# c #CBDFF9", "1# c #CBDEF8", "2# c #CBDDF8", "3# c #CBDDF7", "4# c #ABB8CB", "5# c #7A6871", "6# c #3B3F42", "7# c #85201F", "8# c #AE1C1A", "9# c #A81A18", "0# c #A51816", "a# c #A61816", "b# c #B31C1A", "c# c #BB2625", "d# c #C22D2E", "e# c #D13D3C", "f# c #B33636", "g# c #A3626E", "h# c #C1D5F4", "i# c #C7DCFA", "j# c #C6DCFC", "k# c #C6DCFD", "l# c #C6DAFC", "m# c #C6D9FE", "n# c #C4D9FE", "o# c #C4D9FC", "p# c #C4D8FD", "q# c #C3D9FC", "r# c #C4DAFA", "s# c #C5DAFA", "t# c #C5DAF9", "u# c #C6DAFA", "v# c #C5DBFE", "w# c #C4DCFD", "x# c #D9A9BE", "y# c #F55759", "z# c #D49399", "A# c #CDA7B1", "B# c #ED5055", "C# c #F6292B", "D# c #DAA0B7", "E# c #C5DAFE", "F# c #C9CFF1", "G# c #EF3134", "H# c #D2B1CB", "I# c #CAD7F8", "J# c #D0CCE8", "K# c #C298AA", "L# c #9F5559", "M# c #9C3232", "N# c #BA3534", "O# c #D83938", "P# c #E63030", "Q# c #E93130", "R# c #E92F2E", "S# c #D32827", "T# c #E33231", "U# c #FA3C3B", "V# c #FC3D3D", "W# c #FD3E3D", "X# c #EF3231", "Y# c #A41816", "Z# c #D92B2B", "`# c #DC717D", " $ c #A79FA8", ".$ c #ABB7C4", "+$ c #A1B3CB", "@$ c #C3DAFD", "#$ c #C2D9FE", "$$ c #C3D9FE", "%$ c #C1D9FE", "&$ c #C2D8FE", "*$ c #C2DAFE", "=$ c #C3DAFE", "-$ c #C4DAFD", ";$ c #C5DAFC", ">$ c #CAD2F1", ",$ c #F35157", "'$ c #CEAAAF", ")$ c #ACB2C4", "!$ c #C5C8D5", "~$ c #E8949F", "{$ c #F62729", "]$ c #ED3438", "^$ c #E5909F", "/$ c #E9858F", "($ c #EE777D", "_$ c #F65857", ":$ c #EB5156", "<$ c #CD617C", "[$ c #FBBCBD", "}$ c #F7C3C4", "|$ c #F17472", "1$ c #EE3D36", "2$ c #EE4039", "3$ c #ED3932", "4$ c #EE3C36", "5$ c #EC3934", "6$ c #DA2B26", "7$ c #E22D29", "8$ c #B04B54", "9$ c #A0525F", "0$ c #B34950", "a$ c #D42723", "b$ c #92434D", "c$ c #8E4A57", "d$ c #9C6271", "e$ c #B0626B", "f$ c #AC4D57", "g$ c #8B4B59", "h$ c #6D738B", "i$ c #94A3BE", "j$ c #C6DCFE", "k$ c #C4DBFE", "l$ c #C3D9FD", "m$ c #D57F90", "n$ c #EE4141", "o$ c #BCBCC6", "p$ c #AEB2C1", "q$ c #C2C0C4", "r$ c #E7CDDA", "s$ c #F4282B", "t$ c #F02627", "u$ c #D42823", "v$ c #DC251E", "w$ c #EF2720", "x$ c #ED2720", "y$ c #981A4A", "z$ c #D0A6BD", "A$ c #B6C7ED", "B$ c #DFDCE9", "C$ c #A22C2A", "D$ c #BC2621", "E$ c #A4211D", "F$ c #A12320", "G$ c #B22B27", "H$ c #992321", "I$ c #8A1916", "J$ c #6B5B6F", "K$ c #5B5F75", "L$ c #904D59", "M$ c #DE2A25", "N$ c #655367", "O$ c #555971", "P$ c #555970", "Q$ c #655469", "R$ c #96454E", "S$ c #86515C", "T$ c #453F53", "U$ c #3F4153", "V$ c #A8B9D9", "W$ c #C5D9FE", "X$ c #C5D8FE", "Y$ c #C4D8FE", "Z$ c #C6DDFE", "`$ c #C6ABC3", " % c #DC3333", ".% c #D9D9E1", "+% c #A9AEBD", "@% c #CAC8CE", "#% c #E6E3EF", "$% c #EA5C5F", "%% c #BA1B1A", "&% c #9C1711", "*% c #BF1D18", "=% c #D3221E", "-% c #CD2223", ";% c #812B5C", ">% c #B9BFDB", ",% c #8294D1", "'% c #C68F9F", ")% c #C22D2C", "!% c #752625", "~% c #C43634", "{% c #D63C36", "]% c #E84038", "^% c #E0433D", "/% c #DD4039", "(% c #E5352E", "_% c #794452", ":% c #714656", "<% c #A23B41", "[% c #E12922", "}% c #80414A", "|% c #604E4D", "1% c #61444F", "2% c #724451", "3% c #9A363A", "4% c #61363F", "5% c #4F3437", "6% c #2D2D3E", "7% c #595C73", "8% c #A7B5D6", "9% c #BACFF0", "0% c #C5DDFE", "a% c #C5DEFE", "b% c #BE95A8", "c% c #D87475", "d% c #D5AEB3", "e% c #D6B9C0", "f% c #E2959A", "g% c #B5201F", "h% c #A05057", "i% c #9B5B64", "j% c #9C4A50", "k% c #96282A", "l% c #741428", "m% c #8B5969", "n% c #A3A4AD", "o% c #838BA6", "p% c #AD5255", "q% c #9D2421", "r% c #531311", "s% c #B9211A", "t% c #C1201B", "u% c #C6231C", "v% c #C02119", "w% c #B3241B", "x% c #C8251F", "y% c #74315A", "z% c #74578E", "A% c #952C48", "B% c #D3241E", "C% c #C62B27", "D% c #C4341A", "E% c #C72C1C", "F% c #E02721", "G% c #9F1F1F", "H% c #1A1825", "I% c #5B1E27", "J% c #302E3B", "K% c #323243", "L% c #424356", "M% c #34353B", "N% c #8998AD", "O% c #C3DCFE", "P% c #C4DCFE", "Q% c #C8DEFE", "R% c #C5CBE8", "S% c #C19DB1", "T% c #BF7F8F", "U% c #B37888", "V% c #AD9CB1", "W% c #C3D1EE", "X% c #C7DCFC", "Y% c #C7DDFC", "Z% c #C3D1EF", "`% c #B3BAD8", " & c #B8C3D8", ".& c #B4B9CA", "+& c #915257", "@& c #913231", "#& c #8B1912", "$& c #921912", "%& c #9F2B25", "&& c #A33530", "*& c #A53631", "=& c #A63833", "-& c #AB3935", ";& c #A1393B", ">& c #823A4E", ",& c #A53736", "'& c #AE3531", ")& c #BC3330", "!& c #B73230", "~& c #C33532", "{& c #C83734", "]& c #A93534", "^& c #553237", "/& c #713135", "(& c #4E494D", "_& c #1D1D26", ":& c #25262B", "<& c #292D32", "[& c #9CACC5", "}& c #CDE0FF", "|& c #CEE0FE", "1& c #CDE1FE", "2& c #CDE0FE", "3& c #CEE1FE", "4& c #CDDFFB", "5& c #BFC6DF", "6& c #BFC1D9", "7& c #BBB9D0", "8& c #BEB9CF", "9& c #BD9BAB", "0& c #BE747F", "a& c #B0818C", "b& c #AF7F8A", "c& c #AB737C", "d& c #AC757E", "e& c #AC757F", "f& c #AB747E", "g& c #AB737D", "h& c #AC737C", "i& c #B1828E", "j& c #B38793", "k& c #B38591", "l& c #B48E9C", "m& c #B595A3", "n& c #9092A3", "o& c #ACBDD4", "p& c #CADDFC", "q& c #CBDFFE", "r& c #CBDFFF", "s& c #CEE2FE", "t& c #CEE2FF", "u& c #CFE2FE", "v& c #D1E2FE", "w& c #CFE1FE", "x& c #CCE1FE", "y& c #CCE0FD", "z& c #B2CAE9", "A& c #B0C9E7", "B& c #ABC4E5", "C& c #ABC4E4", "D& c #A8C2E2", "E& c #A4BFE0", "F& c #A5BFE0", "G& c #A4C0E0", "H& c #A4C0E1", "I& c #A3C0E0", "J& c #A9C3E3", "K& c #ABC5E5", "L& c #ABC5E4", "M& c #AAC4E4", "N& c #AAC4E3", "O& c #7D9DC4", "P& c #7D9CC4", "Q& c #7E9DC4", "R& c #7E9DC6", "S& c #7E9EC5", "T& c #7E9DC5", "U& c #7F9EC5", "V& c #7F9EC6", "W& c #809EC6", "X& c #7F9FC6", "Y& c #7C9CC4", "Z& c #7C9CC3", "`& c #7192BA", " * c #7292BA", ".* c #7293BB", "+* c #7392BB", "@* c #7393BC", "#* c #7393BB", "$* c #7594BC", "%* c #7594BD", "&* c #7593BD", "** c #7493BC", "=* c #7494BC", "-* c #7495BC", ";* c #7595BD", ">* c #7595BE", ",* c #7595BF", "'* c #7695BE", ")* c #7695BD", "!* c #7696BE", "~* c #7696BD", "{* c #7594BE", "]* c #7494BD", "^* c #6989B4", "/* c #6889B4", "(* c #6889B3", "_* c #6889B2", ":* c #688AB3", "<* c #698AB3", "[* c #6989B3", "}* c #6A8AB3", "|* c #6A8AB4", "1* c #6A8BB5", "2* c #6A8BB4", "3* c #6B8CB5", "4* c #6C8BB5", "5* c #6C8CB5", "6* c #6A8BB3", "7* c #5D7FA6", "8* c #5C7FA5", "9* c #5D80A5", "0* c #5E81A7", "a* c #5E80A6", "b* c #5E81A6", "c* c #5D80A6", "d* c #5D81A6", "e* c #5E81A8", "f* c #5F81A8", "g* c #5F80A8", "h* c #5E80A7", "i* c #5F81A9", "j* c #6082A9", "k* c #5F82A9", "l* c #6082AA", "m* c #6083AA", "n* c #6082AB", "o* c #6183AB", "p* c #6183AA", "q* c #6183AC", "r* c #6283AC", "s* c #6284AC", "t* c #54769B", "u* c #53759A", "v* c #55769C", "w* c #55779C", "x* c #55779D", "y* c #56779D", "z* c #56789E", "A* c #56789D", "B* c #57799F", "C* c #58799F", "D* c #5879A0", "E* c #5779A0", "F* c #587AA0", "G* c #597AA1", "H* c #597BA1", "I* c #587BA0", "J* c #587AA1", "K* c #597BA3", "L* c #5A7BA3", "M* c #4F7096", "N* c #4F7095", "O* c #4E7095", "P* c #4E6F95", "Q* c #4E7096", "R* c #4F7196", "S* c #507096", "T* c #4F7197", "U* c #507196", "V* c #507197", "W* c #4F7195", "X* c #4A6C90", "Y* c #4B6C91", "Z* c #4B6C92", "`* c #4B6D93", " = c #4A6B91", ".= c #4A6B90", "+= c #4A6C91", "@= c #496B91", "#= c #496B90", "$= c #4A6D92", "%= c #4C6D92", "&= c #496C91", "*= c #4A6B92", "== c #4B6D92", "-= c #4C6D93", ";= c #486A90", ">= c #4A6C92", ",= c #486A8F", "'= c #47698E", ")= c #45688C", "!= c #47698D", "~= c #486A8D", "{= c #476A8F", "]= c #46688E", "^= c #46698E", "/= c #47698F", "(= c #46698D", "_= c #486B90", ":= c #46678C", "<= c #486A8E", "[= c #46688C", "}= c #45698D", "|= c #476A8D", "1= c #46688D", "2= c #476A8E", "3= c #45688D", "4= c #47688D", "5= c #45668B", "6= c #45678C", "7= c #44688C", "8= c #44668C", "9= c #44668A", "0= c #43658A", "a= c #44668B", "b= c #45678D", "c= c #45678B", "d= c #45668C", "e= c #44658B", "f= c #46678B", "g= c #46678D", "h= c #44658A", "i= c #45658A", "j= c #42658A", "k= c #42668A", "l= c #426489", "m= c #43648A", "n= c #436589", "o= c #43668B", "p= c #416589", "q= c #42648A", "r= c #43658B", "s= c #416489", "t= c #416388", "u= c #406488", "v= c #416488", "w= c #406388", "x= c #426488", "y= c #416387", "z= c #3F6387", "A= c #41648A", "B= c #3F6286", "C= c #406287", "D= c #406387", "E= c #406489", "F= c #406288", "G= c #3F6287", "H= c #3F6388", "I= c #416389", "J= c #3F6187", "K= c #3E6187", "L= c #3D6185", "M= c #3E6286", "N= c #3D6285", "O= c #3E6186", "P= c #3E6184", "Q= c #3D6084", "R= c #3D6085", "S= c #3E6386", "T= c #3E6387", "U= c #3E6185", "V= c #3D6186", "W= c #3D6286", "X= c #3E6085", "Y= c #3E6287", "Z= c #3E6388", "`= c #3D6086", " - c #3E6084", ".- c #3F6186", "+- c #3E5F84", "@- c #3D5F84", "#- c #3D5F83", "$- c #3E6086", "%- c #3F6085", "&- c #3C5E82", "*- c #3C5F84", "=- c #47678B", "-- c #587595", ";- c #4D6B8D", ">- c #517091", ",- c #4C6B8D", "'- c #4F6D8F", ")- c #557192", "!- c #496A8C", "~- c #4C6C8F", "{- c #48688B", "]- c #4B6A8C", "^- c #48698B", ". + @ # $ % & * = - ; > , ' & ) ) & ! & ~ { . ] ] ] ] ^ ^ ] ] / ( _ : < [ } | 1 2 2 3 4 5 5 5 5 ", "6 & 7 7 & % 8 9 0 a b a c d * % 7 ! % ~ # e f g h g g i h j h i k l m n o p q r s t u v 5 5 w x ", "y , z A z ; 0 B C C D C ; E c F A 7 6 G 6 ~ # H I J K . L I i ^ ^ g ^ M ] ] ^ N s O O P Q u R S ", "y 7 y T U 9 0 D V D V W D X ; ; Y * F Z ` ...+.@.~ e e #.I i g ^ g ^ ^ ^ ^ ] $.%.&.*.=.-.;.;.>.", "y , ` d ; 9 ; ; 0 ; ,.B '.; 9 ; ).; 0 ; ; ; ; ; !.~.{.~ { ].H + ^.g ] ^ ^ ^ /.(._.:.<.s 2 <.<.<.", "y 7 [.}.Z ; ; c c d c d c ; |.9 ).; ; ; ; B ; 9 ; 8 & 7 ~ +.# # 1.H i I k ^ ] / 2.3.4._._._.:._.", ") +.+.$ % * 5.` ; - ` ` c 8 8 !.F F Z U 6.d U Z ` [.& @.+.7.1.#.8.I i h g ^.^.9.0.a.b.c.d.d.d.e.", "+.# 1.#.#.#.+.{ f.g.h.~ i.~.% & ) & & % j.' & % & ) ) ) ~ @.7.+.k.l.a.$ +.1.{ m.z n.# # h.o.b.p.", "# { 1.1.{ { { #.+.1.{ +.~ ~ ) @.) % % & ) 7 ) ~ ) +.L j +.+.+.+.~ q.r. .* s.Y > t.u.v.w.G # w.x.", "# +.#.+.].#.H #.e { @.& y.& 7 @.{ +.+.+.#.+.#.e j +.z.+.j G ~ ~ , A z g.+.+.+.) A.B.C.C.n.D.G 0.", "E.+.#.F.+.1.#.#.e +.+.) ' & ~ +.g.~ ~ 6 , % G.H.~.~.f.[.& ~ +.1.1.+.I.~ +.+.~ h.J., B.K.K.K.G.h.", "g I 1.f f ].+.# { +.{ ~ ) { 1.#.7.& - L.` ; |.M.N.0 ; ; ,.,.z O.~ ) & & & & & y 5.> |.0 L.s.P.P.", "Q.R.^.h ] ] K L a.$ G & ~ +.e #.e +.S.T.~ i.* > B '.; ; B B 0 c q.% % & % % q.C.U.z * A U.r.P.V.", "R.^ g J g W.i g g I +.~ ~ +.e # 7.{ 7.7.# g.) 7 % , j.X.A A ` 6., 7 6 ~ 7.~ ) G.X.z ,.- Y.0 Z.F ", "8.].].1.+.j g.P.f.f.) ~ 7.G ) G.X.`.* z U > 6.* * Y > |.> > ; U Z }.Y A % % 6 8 +.+++++.+@+@+#+", ") G +.7.% A 8 F }.d s.* q.!.> d c E E ).).E d E E E E d d d E d c ; U |.U > B D $+ +$+%+%+$+$+$+", "A `.X.X.f.* &+* X.* * *+q.* ` ; c c c ).; ; ; ; ` Z ; d c ).E d ).c 9 d ).).; s.%+ + +Y.Y.'.Y. +", "A ` ; c ; > f.@.G ~ S.~.X.A = ; d ; U ; E d U z 8 U 6.d c ).d Z =+r.{.g.{.~ ~ f.A q.G.-+-+;+= ` ", "P. .z A A r.r.r.* U |.|.|.; 9 ; 9 0 0 B 9 ` z Y z d ` Z * * ..g.+.#.e j . . H >+o.G h.o.>+,+'+)+", "z G.!+~+{+1.{.z F z A s.` ` d 8 G.F.g.F.i.X.) ) [.A % ) g.h.+.#.].]+#.#.1.].].8.^+/+(+_+:+<+[+}+", "+.|+1+2+3+4+* * A [.~.f...m.m.X.5+6+7+8+9+0+a+ .6. .~.h.g.{ +.# g.P.b+X.# +.+.8.c+c+d+e+f+<+g+h+", "i+j+k+l+m+n+o+p+r.g.+.#.1.{ q+r+s+t+u+v+w+x+y+z+A+B+#.C+D+~ ~ P.r.O.E+F+G+H+I+J+K+L+M+N+O+P+Q+R+", "S+C+T+U+V+W+X+]+H #.E.#.#.].j h.D.Y+Z+`+ @.@+@@@#@$@%@&@*@=@-@;@>@,@'@9+)@!@~@{@]@^@/@(@_@:@<@[@", "F.1.}@|@1@2@3@1.4@J.5@6@7@8@9@8@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@o+z@z@A@", "B@C@D@E@F@G@H@I@J@K@J@L@M@N@O@P@Q@R@S@T@U@V@W@X@Y@Z@`@ #.#+#@###$#%#Z K@&#*#U@e F.=#-#;#>#,#8.i+", "'#)#!#~#{#]#^#/#(#_#:#<#[#}#|#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#u#", "v#w#x#y#z#A#B#C#D#E#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#U#V#W#X#Y#Z#`# $.$+$@$#$$$n#%$&$%$*$=$-$)#;$", "v#>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$1$2$3$4$5$6$7$8$9$0$a$b$c$d$e$f$g$h$i$j$k$k$=$$$$$l$@$=$)#-$", "m#m$n$o$p$q$r$s$t$u$v$w$x$y$z$A$B$C$D$E$F$G$H$I$u$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$W$X$X$X$Y$Y$X$p#Y$", "Z$`$ %.%+%@%#%$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%|%1%2%3%4%5%6%7%8%9%k$k$k$k$k$k$k$k$", "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%P%P%P%P%P%", "Q%Q%Q%R%S%T%U%V%W%X%Q%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&<&[&k#k#k#k#k#k#k#", "}&|&|&|&|&1&|&1&|&|&|&|&|&2&3&4&5&6&7&8&9&0&a&b&c&c&c&d&e&f&g&h&i&j&k&l&m&n&o&p&q&q&q&r&r&q&q&r&", "s&t&t&t&s&s&s&u&u&u&u&u&u&u&u&u&s&s&s&s&u&v&s&u&u&w&w&w&u&u&s&s&s&s&s&s&s&s&s&3&x&y&y&y&y&y&y&y&", "z&z&z&z&z&A&B&C&C&C&C&C&C&C&C&C&C&C&D&E&E&E&E&E&E&E&F&G&G&F&E&H&H&H&I&J&K&K&K&L&M&M&N&N&N&N&N&N&", "O&O&P&P&Q&Q&R&S&T&S&S&U&U&V&V&V&V&W&V&V&X&X&X&X&X&W&V&V&V&S&S&S&S&S&S&S&S&S&S&T&P&P&Y&Z&Z&Z&Z&Z&", "`&`&`& *`&.*+*@*@*#*#*#*$*%*&***=*-*-*;*>*,*'*'*'*)*!*!*'*~*~*)*)*;*;*>*'*'*'*{*]*]*=***********", "^*/*/*(*_*:*<*<*[*<*[*[*[*[*[*[*[*:*<*[*<*<*<*}*}*|*1*1*2*2*2*3*3*3*4*5*3*3*3*3*2*2*2*2*2*2*6*6*", "7*8*9*9*0*a*b*c*d*e*f*g*h*g*f*f*f*i*i*j*j*k*k*l*m*n*o*o*o*o*o*o*p*q*r*r*s*s*s*q*q*q*q*o*q*r*r*q*", "t*u*v*t*w*t*x*v*w*w*y*x*x*x*x*x*w*z*A*z*A*y*A*A*z*z*B*B*B*B*C*D*E*F*F*G*G*H*I*H*H*G*F*J*K*K*L*K*", "M*N*O*M*O*P*Q*O*Q*Q*N*O*O*M*O*O*O*R*M*Q*P*S*S*O*N*O*O*M*T*M*Q*M*O*U*V*T*O*R*W*V*M*O*N*M*U*S*R*R*", "X*Y*Z*`* =.=+=+=.=.=@=#=$= =%= = =+=X* =+=#=+=&=*===.=-= ===#= =Z* =`*;=+=Z*>=-=,=#=,= =.=#= ='=", ")=,=!=~='='=,={=]=^=/=(=_=:=<=[=,='=,=(=}=}='='=,='=[=|=1=2='='=3=^=3=1=,={=2=4=5=6=)=^=1=(=5=7=", "5=6=8=9=0=a=b=3=6=c=5=8=6=5=b=d=c=0=e=a=f=]=6=6=a=9=a=c=6=6=d=g=5=d=)=6=[=g=6=5=0=h=i=a=d=5=h=j=", "k=9=0=0=0=a=0=l=m=n=0=a=a=j=o=0=p=q=0=a=a=r=j=l=l=j=r=n=l=r=s=t=t=j=r=8=a=j=u=v=w=s=x=t=y=s=t=z=", "A=A=w=z=B=C=D=D=E=D=F=G=G=H=z=t=s=s=w=w=w=C=w=D=w=v=I=l=t=w=I=w=v=v=s=s=t=w=w=G=B=G=C=D=C=J=K=L=", "M=M=M=N=B=M=z=L=O=P=Q=R=L=S=T=C=G=G=U=V=O=U=M=M=G=W=X=L=R=Q=O=Y=z=Z=G=O=L=V=V=Q=L=R=U=L=O=`=R=R=", " -X=X=.-B=U=.-U=R=X=L=R=.-.-X=+- -@-#-X=$-X=%-R=X=R=@-&-*-@-$-O=G=O=X==---;->-,-'-)-!-~-{-]-^-{-"}; searchandrescue_1.5.0/sar/icons/SearchAndRescue5.xpm0000644000175000017500000006050110104532745021457 0ustar jessejesse/* XPM */ static char * SearchAndRescue5_xpm[] = { "48 48 1252 2", " c None", ". c #1F1E1F", "+ c #1E1E1F", "@ c #1E1D1E", "# c #1D1C1D", "$ c #1E1C1E", "% c #1C1B1C", "& c #1F1F20", "* c #212021", "= c #212122", "- c #222122", "; c #222223", "> c #232223", ", c #242324", "' c #242425", ") c #252425", "! c #262526", "~ c #262627", "{ c #272627", "] c #1E1E1E", "^ c #1D1D1D", "/ c #1D1D1E", "( c #201F20", "_ c #202021", ": c #232324", "< c #252526", "[ c #272728", "} c #1F1F1F", "| c #282728", "1 c #282829", "2 c #292829", "3 c #201F21", "4 c #1C1C1C", "5 c #29292B", "6 c #2A292B", "7 c #2B292B", "8 c #202020", "9 c #1C1C1D", "0 c #191919", "a c #181718", "b c #1A191A", "c c #29292A", "d c #181818", "e c #191819", "f c #1B1A1B", "g c #2B2B2C", "h c #212022", "i c #1A1A1A", "j c #1A181A", "k c #1B1B1C", "l c #2B2A2B", "m c #2C2B2C", "n c #2C2C2D", "o c #2D2D2E", "p c #212121", "q c #2A292A", "r c #2A2A2B", "s c #2D2C2D", "t c #2E2D2E", "u c #222222", "v c #1D1E1E", "w c #1F2020", "x c #2C2A2C", "y c #1A1819", "z c #1D1A1A", "A c #1F1B1B", "B c #201C1D", "C c #1F1C1C", "D c #1D1C1C", "E c #1E1F1F", "F c #1C1D1D", "G c #141414", "H c #2E2E2F", "I c #2F2E2F", "J c #262223", "K c #292122", "L c #252223", "M c #1E1B1C", "N c #1E1C1C", "O c #211E1E", "P c #231F20", "Q c #221F20", "R c #211F20", "S c #1D1E1D", "T c #2E2929", "U c #2E2C2D", "V c #2F2F30", "W c #302F30", "X c #232224", "Y c #232323", "Z c #262020", "` c #232020", " . c #252122", ".. c #272122", "+. c #242021", "@. c #232122", "#. c #232021", "$. c #242122", "%. c #272425", "&. c #282627", "*. c #262626", "=. c #1C1A1B", "-. c #2A2424", ";. c #352C2D", ">. c #362D2E", ",. c #332D2E", "'. c #303031", "). c #313031", "!. c #121313", "~. c #100F10", "{. c #161516", "]. c #252324", "^. c #272324", "/. c #292223", "(. c #2A2324", "_. c #242223", ":. c #272223", "<. c #2C2223", "[. c #2C2224", "}. c #2D2526", "|. c #312729", "1. c #302729", "2. c #2D2628", "3. c #2B2829", "4. c #2F2D2F", "5. c #2D2729", "6. c #3E3436", "7. c #3C3234", "8. c #3A3032", "9. c #382F30", "0. c #372F30", "a. c #332F30", "b. c #313132", "c. c #323132", "d. c #191A1A", "e. c #181919", "f. c #181717", "g. c #161515", "h. c #121212", "i. c #1D1B1C", "j. c #231E1F", "k. c #292021", "l. c #2B2223", "m. c #2C2324", "n. c #2D2324", "o. c #2B2324", "p. c #2F2526", "q. c #33292B", "r. c #372C2E", "s. c #392F31", "t. c #372F31", "u. c #332D2F", "v. c #312F30", "w. c #333133", "x. c #353335", "y. c #363436", "z. c #373436", "A. c #343234", "B. c #3B3739", "C. c #453C3E", "D. c #493E40", "E. c #473C3F", "F. c #443A3C", "G. c #423739", "H. c #3F3536", "I. c #3A3233", "J. c #363132", "K. c #333233", "L. c #1C1B1B", "M. c #1B1A1A", "N. c #1A1919", "O. c #151414", "P. c #201D1D", "Q. c #262021", "R. c #312728", "S. c #362C2E", "T. c #3B3032", "U. c #3E3335", "V. c #413538", "W. c #3C3537", "X. c #363235", "Y. c #373537", "Z. c #3B383A", "`. c #3D3A3C", " + c #3E3B3E", ".+ c #3C383B", "++ c #484043", "@+ c #53474B", "#+ c #53474A", "$+ c #514649", "%+ c #4F4446", "&+ c #4C4144", "*+ c #483F41", "=+ c #453B3D", "-+ c #3A3738", ";+ c #343435", ">+ c #343334", ",+ c #333334", "'+ c #262426", ")+ c #272426", "!+ c #282525", "~+ c #1F1D1E", "{+ c #1F1C1D", "]+ c #1E1B1B", "^+ c #1D1B1B", "/+ c #1B1B1B", "(+ c #171717", "_+ c #191818", ":+ c #342C2D", "<+ c #403537", "[+ c #44393C", "}+ c #473C40", "|+ c #423C3F", "1+ c #454144", "2+ c #4A4649", "3+ c #4B474B", "4+ c #524D51", "5+ c #5E5256", "6+ c #605358", "7+ c #5D5154", "8+ c #5B4E52", "9+ c #584D50", "0+ c #554A4E", "a+ c #50474A", "b+ c #4A4447", "c+ c #454143", "d+ c #403D3E", "e+ c #39383A", "f+ c #353536", "g+ c #353435", "h+ c #2A2526", "i+ c #2C2526", "j+ c #2A2425", "k+ c #2B2526", "l+ c #242020", "m+ c #221E1E", "n+ c #2A2829", "o+ c #322C2E", "p+ c #3E3638", "q+ c #473D40", "r+ c #4A4448", "s+ c #544F54", "t+ c #514C51", "u+ c #565156", "v+ c #5A555A", "w+ c #625C62", "x+ c #6C656B", "y+ c #6F656B", "z+ c #716268", "A+ c #6C5E63", "B+ c #66585D", "C+ c #605357", "D+ c #585054", "E+ c #504D50", "F+ c #4D494C", "G+ c #494649", "H+ c #444244", "I+ c #403F41", "J+ c #3C3B3C", "K+ c #393738", "L+ c #383738", "M+ c #373738", "N+ c #272527", "O+ c #282526", "P+ c #2B2627", "Q+ c #2D2627", "R+ c #2F2627", "S+ c #262121", "T+ c #262122", "U+ c #252021", "V+ c #221F1F", "W+ c #201E1E", "X+ c #242424", "Y+ c #343233", "Z+ c #383538", "`+ c #433F42", " @ c #645F64", ".@ c #5A575A", "+@ c #666065", "@@ c #776F76", "#@ c #7A7279", "$@ c #797178", "%@ c #7A6F76", "&@ c #776B72", "*@ c #655D63", "=@ c #5A565A", "-@ c #555154", ";@ c #514D51", ">@ c #4C494C", ",@ c #474547", "'@ c #424042", ")@ c #433E3F", "!@ c #443B3C", "~@ c #403839", "{@ c #393839", "]@ c #383839", "^@ c #2A2728", "/@ c #262324", "(@ c #282324", "_@ c #272323", ":@ c #292324", "<@ c #282323", "[@ c #262323", "}@ c #272526", "|@ c #2C292B", "1@ c #302E30", "2@ c #4E3232", "3@ c #453335", "4@ c #5A464A", "5@ c #544C50", "6@ c #675154", "7@ c #615C61", "8@ c #6F6871", "9@ c #746E78", "0@ c #777077", "a@ c #807880", "b@ c #847C84", "c@ c #827A81", "d@ c #7D767C", "e@ c #766F76", "f@ c #6E686D", "g@ c #595559", "h@ c #545154", "i@ c #4F4C4F", "j@ c #4A474A", "k@ c #464244", "l@ c #453F41", "m@ c #494041", "n@ c #433B3D", "o@ c #3B3A3B", "p@ c #3A3A3B", "q@ c #3A393B", "r@ c #39393B", "s@ c #2A2627", "t@ c #292728", "u@ c #282828", "v@ c #312F31", "w@ c #444042", "x@ c #5B383A", "y@ c #62494C", "z@ c #865A5D", "A@ c #854E51", "B@ c #806067", "C@ c #726A73", "D@ c #79707A", "E@ c #7A7481", "F@ c #7C7580", "G@ c #7D777F", "H@ c #8B828A", "I@ c #8E858D", "J@ c #857D85", "K@ c #7B747B", "L@ c #6F6A6F", "M@ c #625E63", "N@ c #585458", "O@ c #525053", "P@ c #4D4B4D", "Q@ c #494648", "R@ c #464445", "S@ c #414041", "T@ c #3E3E3F", "U@ c #3E3D3E", "V@ c #3D3D3E", "W@ c #3D3C3D", "X@ c #2B2A2C", "Y@ c #383638", "Z@ c #3F3D3F", "`@ c #454245", " # c #494548", ".# c #524E52", "+# c #6E494C", "@# c #885459", "## c #936369", "$# c #917078", "%# c #817888", "&# c #8A8091", "*# c #918592", "=# c #988C98", "-# c #988E97", ";# c #91898F", "># c #8A8289", ",# c #918890", "'# c #928992", ")# c #898188", "!# c #7C767C", "~# c #6F6A6E", "{# c #615D61", "]# c #585558", "^# c #535053", "/# c #4D4A4C", "(# c #4C4749", "_# c #514A4C", ":# c #494446", "<# c #434041", "[# c #413F40", "}# c #3F3F40", "|# c #2A2A2C", "1# c #2C2B2D", "2# c #3C3A3C", "3# c #413E41", "4# c #423F42", "5# c #444144", "6# c #805255", "7# c #815F67", "8# c #81727C", "9# c #A07D85", "0# c #928899", "a# c #A194A4", "b# c #B3A4B2", "c# c #BEB0BD", "d# c #BFB3BD", "e# c #B8ACB6", "f# c #A69DA5", "g# c #918A90", "h# c #9A9198", "i# c #9D959D", "j# c #7E777E", "k# c #767176", "l# c #6B676B", "m# c #5E5B5E", "n# c #585658", "o# c #525052", "p# c #504D4F", "q# c #594E51", "r# c #524849", "s# c #4A4344", "t# c #484243", "u# c #464243", "v# c #444142", "w# c #424142", "x# c #3A383A", "y# c #3C393C", "z# c #3E3C3F", "A# c #4D4A4D", "B# c #63575C", "C# c #8A595D", "D# c #836B74", "E# c #AF797E", "F# c #A68F9A", "G# c #C49FAB", "H# c #C5ABBA", "I# c #D7C4D3", "J# c #E4D3E2", "K# c #E9D9E6", "L# c #DED0DC", "M# c #C7BBC6", "N# c #ABA1A9", "O# c #ADA2AB", "P# c #B1A4AD", "Q# c #A1929A", "R# c #8A7E84", "S# c #746D72", "T# c #625E62", "U# c #5A5557", "V# c #5C5456", "W# c #494748", "X# c #474445", "Y# c #484445", "Z# c #464344", "`# c #434344", " $ c #454345", ".$ c #545053", "+$ c #6A5A5F", "@$ c #8D6368", "#$ c #AD7672", "$$ c #D58284", "%$ c #DA9FA6", "&$ c #F2A4B0", "*$ c #FEC3D3", "=$ c #FCE1F1", "-$ c #FDF6FD", ";$ c #FEFAFE", ">$ c #FBF0FA", ",$ c #E8D6E3", "'$ c #CAB7C1", ")$ c #C0B1BB", "!$ c #C1AEB9", "~$ c #B2A0A9", "{$ c #A29199", "]$ c #918389", "^$ c #7E7176", "/$ c #696165", "($ c #544F52", "_$ c #5A5355", ":$ c #63595B", "<$ c #5B5354", "[$ c #554B4D", "}$ c #514849", "|$ c #4D4748", "1$ c #474647", "2$ c #2C2C2C", "3$ c #414142", "4$ c #605458", "5$ c #77585D", "6$ c #A26769", "7$ c #C97776", "8$ c #D79397", "9$ c #DA909A", "0$ c #F6AEBC", "a$ c #FFD2E3", "b$ c #FFF3FD", "c$ c #FFFEFF", "d$ c #FFFFFF", "e$ c #FFFDFE", "f$ c #FFE7F3", "g$ c #F8CEDA", "h$ c #D7C7D3", "i$ c #C3B6C1", "j$ c #B9A8B1", "k$ c #A999A1", "l$ c #998A91", "m$ c #897B80", "n$ c #7E7276", "o$ c #776B6F", "p$ c #706568", "q$ c #695E61", "r$ c #625759", "s$ c #5A5152", "t$ c #554C4D", "u$ c #4E4B4C", "v$ c #4A4A4B", "w$ c #49494A", "x$ c #323233", "y$ c #3B3B3C", "z$ c #464646", "A$ c #828283", "B$ c #818182", "C$ c #5B5A5B", "D$ c #4B4A4C", "E$ c #76494B", "F$ c #935E65", "G$ c #B37177", "H$ c #C98789", "I$ c #CB868D", "J$ c #D8929D", "K$ c #F3B1BF", "L$ c #FED5E5", "M$ c #FFF5FD", "N$ c #FFF2FA", "O$ c #FBEDF8", "P$ c #DECFDC", "Q$ c #CBBDC7", "R$ c #BEAEB7", "S$ c #AF9EA6", "T$ c #9E8F96", "U$ c #8D8085", "V$ c #83777B", "W$ c #7C7174", "X$ c #756A6D", "Y$ c #6E6466", "Z$ c #675D5F", "`$ c #5F5657", " % c #5A5253", ".% c #585051", "+% c #554F50", "@% c #554E4F", "#% c #2F2F2F", "$% c #353233", "%% c #3B3233", "&% c #393435", "*% c #494849", "=% c #858585", "-% c #EDEEED", ";% c #DDDADB", ">% c #797576", ",% c #5C5558", "'% c #574A4D", ")% c #894B4A", "!% c #8A6174", "~% c #B17A7F", "{% c #BB777C", "]% c #C7838B", "^% c #D3949E", "/% c #E9ADB9", "(% c #FDCBD8", "_% c #FFE9F5", ":% c #FFFDFF", "<% c #FBEAF6", "[% c #E4CFDB", "}% c #D3C0CA", "|% c #C3B1BB", "1% c #B3A3AB", "2% c #A3959B", "3% c #93868B", "4% c #8A7E82", "5% c #83777A", "6% c #6D6365", "7% c #655C5E", "8% c #615859", "9% c #605657", "0% c #5E5556", "a% c #5C5354", "b% c #373031", "c% c #3A3132", "d% c #383233", "e% c #3A3334", "f% c #393334", "g% c #363536", "h% c #4A494A", "i% c #827E7F", "j% c #E4C8C8", "k% c #D9B3B2", "l% c #7C7375", "m% c #635A5C", "n% c #6E4647", "o% c #924844", "p% c #A26362", "q% c #AB6A6D", "r% c #B57279", "s% c #C1838B", "t% c #CD939D", "u% c #DAA2AB", "v% c #EFBAC2", "w% c #FED6E0", "x% c #FFEAF5", "y% c #FFF6FC", "z% c #FFFEFE", "A% c #FEF8FE", "B% c #F6E2EE", "C% c #E5D1DC", "D% c #D6C3CD", "E% c #C6B5BD", "F% c #B5A6AD", "G% c #A5979D", "H% c #94898E", "I% c #8C8286", "J% c #877B7F", "K% c #807578", "L% c #786D70", "M% c #6F6668", "N% c #665F61", "O% c #605B5C", "P% c #615A5B", "Q% c #5F5758", "R% c #363031", "S% c #373334", "T% c #363334", "U% c #472B2B", "V% c #3A3435", "W% c #433F40", "X% c #5E5758", "Y% c #935E5C", "Z% c #A25454", "`% c #6E6163", " & c #615659", ".& c #6D4545", "+& c #8E4844", "@& c #975758", "#& c #A05F65", "$& c #AC7076", "%& c #B98088", "&& c #C38D95", "*& c #CE9BA1", "=& c #DDA9B0", "-& c #F1BDC5", ";& c #FCD3DD", ">& c #FFF5FB", ",& c #FFF7FD", "'& c #FDEBF7", ")& c #F3DFEA", "!& c #E7D4DE", "~& c #D8C7D0", "{& c #C8B8C0", "]& c #B2A8AF", "^& c #9F999E", "/& c #918C91", "(& c #898689", "_& c #847F83", ":& c #7C787B", "<& c #747274", "[& c #6B6B6C", "}& c #646465", "|& c #616162", "1& c #605F60", "2& c #5F5D5E", "3& c #5C5B5C", "4& c #303030", "5& c #3B3132", "6& c #3C3233", "7& c #3C3334", "8& c #3B3435", "9& c #3C3536", "0& c #542726", "a& c #483233", "b& c #42393A", "c& c #4A4142", "d& c #633C3C", "e& c #782E2D", "f& c #634646", "g& c #5F5559", "h& c #6A403E", "i& c #8A4F4E", "j& c #8E4D4F", "k& c #975C61", "l& c #A26B71", "m& c #AD7A7F", "n& c #B7868A", "o& c #C69499", "p& c #D5A3A9", "q& c #E4B6BD", "r& c #F5DBE6", "s& c #FDEAF5", "t& c #FEEBF7", "u& c #FAE6F1", "v& c #F1DEE8", "w& c #E6D4DD", "x& c #CABAC1", "y& c #B9ABB1", "z& c #A99CA1", "A& c #9E9397", "B& c #968C90", "C& c #8D8588", "D& c #847E81", "E& c #7B7779", "F& c #747071", "G& c #6B696B", "H& c #686768", "I& c #666566", "J& c #626263", "K& c #353132", "L& c #3D3435", "M& c #403637", "N& c #543B2B", "O& c #55552D", "P& c #43393A", "Q& c #453C3D", "R& c #563030", "S& c #6E2421", "T& c #613332", "U& c #635661", "V& c #814543", "W& c #834443", "X& c #85484B", "Y& c #90575B", "Z& c #9C6669", "`& c #9F7173", " * c #AE8083", ".* c #BE9094", "+* c #D0ACB2", "@* c #E2CDD7", "#* c #EDDAE5", "$* c #F5E2EC", "%* c #F8E5EF", "&* c #F4E2EC", "** c #EEDCE5", "=* c #E4D3DC", "-* c #D8C9D0", ";* c #CABCC3", ">* c #BBAEB3", ",* c #AEA2A7", "'* c #A1999D", ")* c #999296", "!* c #958B8E", "~* c #8C8386", "{* c #857B7D", "]* c #7D7475", "^* c #776F70", "/* c #756D6E", "(* c #736B6C", "_* c #6F6869", ":* c #6C6667", "<* c #413738", "[* c #515534", "}* c #54781E", "|* c #3F1D18", "1* c #401F1C", "2* c #47201D", "3* c #5A201B", "4* c #5F2724", "5* c #6D5760", "6* c #7D4B49", "7* c #794240", "8* c #7B4749", "9* c #AD5556", "0* c #D86465", "a* c #9A6E6D", "b* c #AB8182", "c* c #BCA3AA", "d* c #CDBBC4", "e* c #DAC8D1", "f* c #E4D2DC", "g* c #ECDAE3", "h* c #EFDFE8", "i* c #EDDFE8", "j* c #E9DAE2", "k* c #E2D2DA", "l* c #D2C8CE", "m* c #C2BCC2", "n* c #B8B0B5", "o* c #B0A8AC", "p* c #A39FA3", "q* c #9A979A", "r* c #939093", "s* c #8A888A", "t* c #848183", "u* c #7C797A", "v* c #787576", "w* c #7A7374", "x* c #787172", "y* c #746F70", "z* c #706D6E", "A* c #3B3333", "B* c #3C3333", "C* c #3D3334", "D* c #3E3536", "E* c #413839", "F* c #45393A", "G* c #463C3D", "H* c #463B3C", "I* c #463838", "J* c #553634", "K* c #4D3938", "L* c #602722", "M* c #6B5059", "N* c #786061", "O* c #795252", "P* c #8D5956", "Q* c #985E5B", "R* c #977475", "S* c #C37D7E", "T* c #C0A8AE", "U* c #BFB3BA", "V* c #D0C1C8", "W* c #DBCBD3", "X* c #E3D4DB", "Y* c #E5D9E0", "Z* c #E1DAE1", "`* c #DDD7DD", " = c #D7CFD6", ".= c #CBC6CB", "+= c #C1BDC1", "@= c #B9B6BA", "#= c #B1AEB2", "$= c #A9A6A9", "%= c #A09DA0", "&= c #989698", "*= c #908F91", "== c #878788", "-= c #837F81", ";= c #857C7D", ">= c #807A7B", ",= c #787879", "'= c #767576", ")= c #737374", "!= c #3F3637", "~= c #423839", "{= c #433A3B", "]= c #453D3E", "^= c #463E3F", "/= c #483F40", "(= c #6B5757", "_= c #554F4F", ":= c #782A26", "<= c #693234", "[= c #604349", "}= c #5F595F", "|= c #776163", "1= c #79686A", "2= c #7D6668", "3= c #876C6D", "4= c #B47778", "5= c #CEA3A8", "6= c #B2ABB1", "7= c #C1B9BF", "8= c #D1C3C9", "9= c #D8CBD1", "0= c #DCD2D8", "a= c #E0D6DB", "b= c #D9D3D9", "c= c #D1CDD2", "d= c #CBC7CB", "e= c #C5C1C6", "f= c #BEBBBF", "g= c #B7B4B8", "h= c #AEABAE", "i= c #A3A2A4", "j= c #9D9A9B", "k= c #989293", "l= c #928A8B", "m= c #8D8586", "n= c #898283", "o= c #837F80", "p= c #7D7C7D", "q= c #7B7B7C", "r= c #7A7879", "s= c #3C3335", "t= c #3E3435", "u= c #4F4142", "v= c #6D6060", "w= c #6D6766", "x= c #712B27", "y= c #5A3230", "z= c #594847", "A= c #615F61", "B= c #6C686B", "C= c #747173", "D= c #7B787C", "E= c #858184", "F= c #90888C", "G= c #A0969A", "H= c #ADA3A7", "I= c #B9AFB4", "J= c #C4BABF", "K= c #CCC4C9", "L= c #D1CBCF", "M= c #D5D0D5", "N= c #D5D1D6", "O= c #D2CFD3", "P= c #CECBCF", "Q= c #C9C6C9", "R= c #C1BEC2", "S= c #B9B7BA", "T= c #B0AEB1", "U= c #A7A5A7", "V= c #9E9D9F", "W= c #989798", "X= c #929192", "Y= c #928D8E", "Z= c #8E8A8B", "`= c #858485", " - c #878182", ".- c #877E7F", "+- c #383335", "@- c #403738", "#- c #443C3D", "$- c #463D3E", "%- c #473E3F", "&- c #494142", "*- c #4C4445", "=- c #584140", "-- c #736A69", ";- c #7C6461", ">- c #642C2A", ",- c #56403F", "'- c #5D5657", ")- c #655F60", "!- c #6C6769", "~- c #757072", "{- c #7B777A", "]- c #837F82", "^- c #8B888C", "/- c #999598", "(- c #A4A0A4", "_- c #AFACB0", ":- c #C2BFC3", "<- c #CBC8CC", "[- c #D2CED2", "}- c #D5D1D5", "|- c #D3D0D4", "1- c #CFCCD0", "2- c #CAC7CB", "3- c #C3C1C4", "4- c #BCBBBD", "5- c #B4B3B5", "6- c #ABAAAB", "7- c #A3A3A4", "8- c #9D9C9D", "9- c #99999A", "0- c #959596", "a- c #919091", "b- c #8C8C8D", "c- c #89898A", "d- c #8B8485", "e- c #373435", "f- c #3D3536", "g- c #3F3738", "h- c #403838", "i- c #4C4344", "j- c #9A827D", "k- c #94807B", "l- c #753E3C", "m- c #582F2D", "n- c #5B4D4D", "o- c #615758", "p- c #665E5F", "q- c #706668", "r- c #776E70", "s- c #807678", "t- c #887D80", "u- c #91878A", "v- c #9D9497", "w- c #A89FA2", "x- c #B1AAAD", "y- c #BBB4B8", "z- c #C3BEC1", "A- c #CCC6C9", "B- c #D2CBCF", "C- c #D7CED2", "D- c #D3CFD2", "E- c #D2CED1", "F- c #D0CBCD", "G- c #CBC5C8", "H- c #C0BEC0", "I- c #B6B5B7", "J- c #ADACAD", "K- c #A6A6A7", "L- c #A7A2A4", "M- c #A49FA0", "N- c #9B9B9C", "O- c #989899", "P- c #979394", "Q- c #958E90", "R- c #928C8D", "S- c #91898A", "T- c #353136", "U- c #363337", "V- c #373437", "W- c #3A3839", "X- c #41393B", "Y- c #484041", "Z- c #4E4445", "`- c #52494A", " ; c #908783", ".; c #815753", "+; c #5D3230", "@; c #57403F", "#; c #635A5B", "$; c #685F60", "%; c #6D6566", "&; c #756C6D", "*; c #867C7E", "=; c #908688", "-; c #9C9194", ";; c #A79DA0", ">; c #B3A9AB", ",; c #BDB2B5", "'; c #C5BBBE", "); c #CCC2C5", "!; c #D3C8CB", "~; c #D9CED0", "{; c #DAD0D3", "]; c #DACFD2", "^; c #D6CCCE", "/; c #CFC6C8", "(; c #C5BFC0", "_; c #B8B7B8", ":; c #B0B0B1", "<; c #ADADAE", "[; c #AAA9AA", "}; c #A8A6A7", "|; c #A5A1A2", "1; c #A29C9D", "2; c #A09899", "3; c #9C9495", "4; c #999192", "5; c #968D8E", "6; c #363437", "7; c #373337", "8; c #373438", "9; c #3C373D", "0; c #413A3E", "a; c #473F40", "b; c #4B4243", "c; c #4D4445", "d; c #4F4647", "e; c #544B4C", "f; c #564E4F", "g; c #595152", "h; c #62595A", "i; c #665D5E", "j; c #6A6263", "k; c #6F6667", "l; c #746B6D", "m; c #7B7374", "n; c #847A7C", "o; c #8E8486", "p; c #998F91", "q; c #A59B9D", "r; c #AFA5A7", "s; c #B8ADB0", "t; c #C1B7B9", "u; c #CABFC2", "v; c #D0C7C9", "w; c #D5CBCD", "x; c #D8CED0", "y; c #CEC6C7", "z; c #C8BFC1", "A; c #C2BABB", "B; c #BDB6B7", "C; c #B9B2B3", "D; c #B5AEB0", "E; c #B1ABAC", "F; c #ADA7A8", "G; c #A9A3A4", "H; c #A79E9F", "I; c #A39A9B", "J; c #9F9798", "K; c #3A373C", "L; c #3C393D", "M; c #3F3C3F", "N; c #4B4344", "O; c #514748", "P; c #534A4B", "Q; c #564D4F", "R; c #605758", "S; c #645B5C", "T; c #686061", "U; c #6D6465", "V; c #73696A", "W; c #766E6F", "X; c #7C7475", "Y; c #837A7B", "Z; c #8C8385", "`; c #968C8E", " > c #9E9597", ".> c #A9A0A2", "+> c #B4ABAD", "@> c #BDB4B6", "#> c #C5BCBD", "$> c #CBC2C4", "%> c #D0C7C8", "&> c #D4CACC", "*> c #D5CCCD", "=> c #D4CBCC", "-> c #CFC7C8", ";> c #CCC3C4", ">> c #C8BFC0", ",> c #C2B9BA", "'> c #BEB6B7", ")> c #BBB2B4", "!> c #B6ADAE", "~> c #B1A9AA", "{> c #ADA4A6", "]> c #A89FA0", "^> c #A49B9C", "/> c #A1999A", "(> c #383338", "_> c #3B383C", ":> c #3E3A3E", "<> c #413D41", "[> c #434144", "}> c #454445", "|> c #4E4748", "1> c #53494A", "2> c #554C4E", "3> c #574F50", "4> c #5D5556", "5> c #675E5F", "6> c #6B6364", "7> c #716768", "8> c #7A7172", "9> c #807778", "0> c #867D7E", "a> c #8C8485", "b> c #948A8B", "c> c #9C9394", "d> c #B0A7A8", "e> c #B8AEB0", "f> c #BFB6B8", "g> c #C6BDBE", "h> c #D1C8CA", "i> c #D4CCCD", "j> c #D0CACB", "k> c #CDC5C6", "l> c #CAC2C3", "m> c #C7BEBF", "n> c #C3BABB", "o> c #BAB2B3", "p> c #B1A8A9", "q> c #ACA4A5", "r> c #A9A0A1", "s> c #A59C9D", "t> c #3C3438", "u> c #3B3539", "v> c #3E383E", "w> c #403E40", "x> c #424143", "y> c #444045", "z> c #484347", "A> c #4F4849", "B> c #544C4D", "C> c #574E4F", "D> c #655B5C", "E> c #696162", "F> c #6E6566", "G> c #72696A", "H> c #786F70", "I> c #7E7576", "J> c #888081", "K> c #8E8687", "L> c #988F90", "M> c #A09798", "N> c #A69D9F", "O> c #AEA5A6", "P> c #B5ACAD", "Q> c #BDB5B6", "R> c #CBC3C4", "S> c #D0C8C9", "T> c #D3CDCE", "U> c #D3CBCC", "V> c #D1C9CA", "W> c #C3BBBC", "X> c #BFB7B8", "Y> c #BBB2B3", "Z> c #B0A8A9", "`> c #ADA5A6", " , c #A9A1A2", "., c #413739", "+, c #463C40", "@, c #473F42", "#, c #484144", "$, c #4A4145", "%, c #4C4648", "&, c #4F4A4B", "*, c #584F50", "=, c #5D5455", "-, c #706768", ";, c #7C7374", ">, c #8B8384", ",, c #9B9394", "', c #A19899", "), c #AFA7A8", "!, c #B7AEAF", "~, c #C5BBBC", "{, c #CAC1C3", "], c #D7CECF", "^, c #D8CFD0", "/, c #BAB1B2", "(, c #B6ACAD", "_, c #AEA6A7", ":, c #4A4243", "<, c #4D4344", "[, c #736A6B", "}, c #786F71", "|, c #82797A", "1, c #898081", "2, c #908788", "3, c #968C8D", "4, c #9B9294", "5, c #AAA2A3", "6, c #B2A9AA", "7, c #B9B0B1", "8, c #D6CDCE", "9, c #DAD1D2", "0, c #DAD1D3", "a, c #D2CACB", "b, c #CBC2C3", "c, c #B7ADAE", "d, c #B2AAAB", "e, c #4E4546", "f, c #655C5D", "g, c #6A6162", "h, c #746C6D", "i, c #797071", "j, c #7E7677", "k, c #918889", "l, c #9D9596", "m, c #A69D9E", "n, c #ACA3A4", "o, c #B3AAAB", "p, c #C0B8B9", "q, c #D9D0D1", ". . + @ # $ @ # # # # # % % % % % % % # @ @ @ . . & * * * = - - ; > > > , , , , , ' ) ) ! ! ~ { ", ". ] . @ @ ^ @ / # # # # # % % % % % % # @ @ + & ( ( _ * * = - - ; > > : , , ' ) ) < ! ! ~ { { { ", ". ] . . @ @ @ @ @ @ @ # # # % % % # # # @ . . . ( ( _ * * = - - > > : , , ) ) ) < ! ! ~ ~ { { { ", ". . . . . @ @ @ . @ @ # # # # # # # # @ @ . . . ( ( _ * * - - > , , , ) ) ) ) < ! ! ! ~ { { { [ ", "} . . . . . . . . . @ / # @ @ # # # # @ @ . . . ( ( * * - > > > , , ' ) ) < ) < ! ! ~ { { { [ [ ", ". & & & . . & . . . + @ @ @ @ # # # # @ @ @ . . ( ( * - - > > > , , ' ) ) < ! ! ~ { { [ | | 1 2 ", "( ( 3 ( & } ( . . . . . . @ @ @ # # # @ @ @ @ @ . 4 # . _ - > > , , ) ) ~ { { | | 1 2 2 2 5 6 7 ", "_ * 8 3 ( & ( ( ( ( ( . . + @ @ @ @ @ @ @ # 4 9 # 0 a a b 4 & , ) ! ! { [ | | | 1 2 2 2 c 6 7 7 ", "* _ 8 8 ( ( ( ( * ( ( . . . . . . @ @ . @ # 4 % 4 0 d e f # . ( * , ! { | | | | 1 2 2 c 6 7 7 g ", "h * _ * * * * * * * ( ( ( ( . . . . @ . @ # # 4 # i i j k # + } ] 4 ( ~ | 1 2 2 6 7 l g m m n o ", "p p = = = p - * * * * _ ( ( ( & . . . . . @ / # # i 0 e k # ] ] 9 4 ^ & ~ c q r m m n s s o t t ", "- - - u - = - = * * * * * _ ( ( ( ( ( ( ( . @ # % b e b 4 # ] 4 4 ^ v ] w | x m n n s s o t t t ", "; ; u u u - - - - - - = * * * * * * * * ( ( @ @ % i y z A B C D ^ ] E } F G 1 s s t t t H I I I ", "> > > > J K L ; > > ; - - - - - - = * * * * . @ D M N O P Q R } } } } S C T U o t t H I I V V W ", "> X Y > L Z ` - - - > > ; > > > - - ...+.* - @.#.$.L %.&.&.| { *., =.-.;.>.,.t I I V W W '.).).", ": > , > = !.~.{.. * - > ].^./.(._._.:.<.[.}.|.1.2.3.x U 4.I I t ! 5.6.7.8.9.0.a.'.b.).).b.c.c.c.", ", , , , * d.e.f.g.h.i.j.k.l.m.n.m.o.m.p.q.r.s.t.u.v.w.x.y.z.A.B.C.D.E.F.G.H.I.J.K.K.K.K.K.K.K.K.", ") ) ) ) - i i f L.M.N.O.O.P.Q.K l.n.R.S.T.U.V.W.X.Y.Z.`. +.+++@+#+$+%+&+*+=+-+;+>+,+>+>+>+,+>+>+", "'+)+'+!+].~+{+C C ]+^+L.L./+(+_+]+-.:+8.<+[+}+|+ +1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+g+f+f+g+g+g+", "h+i+j+k+j++.l+P m+O P.N D 4 4 4 . ) 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+L+L+M+M+M+", "N+O+P+Q+R+:.S+T+T+U++.P V+O W+R X+q I Y+Z+`+F+ @.@+@@@#@#@$@%@&@y+*@=@-@;@>@,@'@)@!@~@{@{@{@{@]@", "{ &.| ^@3.%./@(@_@:.:@(@<@^.[@}@|@1@x.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@", "[ | | 2 2 | { ~ ~ { s@t@| u@q v@Y. +w@x@y@z@A@B@C@D@E@F@G@b@H@I@J@K@L@M@N@O@P@Q@R@,@S@T@U@V@U@W@", "2 2 2 c 5 c 2 2 q l X@g m m W Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#]#^#/#(#_#:#<#S@[#}#}#", "2 q q 7 7 |#g 1#n s s s t I g+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#", "q l x x x m s s o o t H W c.Y.x#y#z#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T#m#]#U#V#p#W#X#Y#Z#`#", "g 1#n n o o t t t H V ).c.w.A.c.x# $.$+$@$#$$$%$&$*$=$-$;$>$,$'$)$!$~${$]$^$/$($_$:$<$[$}$|$W#1$", "2$s s t t t H H I '.c.,+q@S@3$w#I+G+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$", "s o t H H H I V b.x$K.y$z$A$B$C$D$A#E$F$G$H$I$J$K$L$M$c$d$c$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$`$ %.%+%@%", "t H I V #%v.v.c.$%%%&%*%=%-%;%>%,%'%)%!%~%{%]%^%/%(%_%e$c$:%e$<%[%}%|%1%2%3%4%5%W$X$6%7%8%9%0%a%", "I I I W v.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%8%Q%", "V V V W R%c%I.S%T%U%V%W%X%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&;&>&,&'&)&!&~&{&]&^&/&(&_&:&<&[&}&|&1&2&3&", "'.4&'.J.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&I.6&7&L&H.M&N&O&P&Q&R&S&T&U&V&W&X&Y&Z&`& *.*+*@*#*$*%*&***=*-*;*>*,*'*)*!*~*{*]*^*/*(*_*:*", ").x$,+S%7&L&H.M&<*[*}*|*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*", "Y+I.A*B*C*D*M&E*b&F*G*H*I*J*K*L*M*]*N*O*P*Q*R*S*T*U*V*W*X*Y*Z*`* =.=+=@=#=$=%=&=*===-=;=>=,='=)=", "6&7&7&C*D*!=<*~={=]=^=/=c&(=_=:=<=[=}=|=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=", "7&s=L&t=!=<*~={=]=^=/=c&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=U=V=W=X=Y=Z===`= -.-", "+-L&t=H.@-E*b&#-$-%-&-*-=---;->-,-'-)-!-~-{-]-^-/-(-_-@=:-<-[-}-|-1-2-3-4-5-6-7-8-9-0-a-b-c-==d-", "x.e-f-g-h-b&F.Q&^=&-i-r#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-U-V-Y@W-X-Q&^=Y-i-Z-`- ;.;+;@;9%#;$;%;&;]**;=;-;;;>;,;';);!;~;{;];^;/;(;_;:;<;[;};|;1;2;3;4;5;", "6;7;8;L+x#9;0;a;b;c;d;}$e;f;g;0%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;3;", "Y.Y@Z+e+K;L;M;w@N;d;O;P;Q;.%<$R;S;T;U;V;W;X;Y;Z;`; >.>+>@>#>$>%>&>*>=>->;>>>#>,>'>)>!>~>{>]>^>/>", "(>Z+]@r@_>:><>[>}>|>1>2>3>s$4>h;5>6>7>l;8>9>0>a>b>c>H;d>e>f>g>$>h>=>i>j>->k>l>m>n>'>o>!>p>q>r>s>", "t>u>B..+v>w>x>y>z>A>B>C>g;<$`$D>E>F>G>H>I>Y;J>K>L>M>N>O>P>Q>#>R>S>=>i>T>U>V>y;$>>>W>X>Y>!>Z>`> ,", ".,~=b&!@+,@,#,$,%,&,f;*, %=,h;5>6>-,&;;,9>;=>,b>,,',]>),!,'>~,{,->i>],^,^,*>U>->;>>>n>'>/,(,~>_,", "~=b&{=]=a;:,<,d;`-t$3>g;<$9%S;T;U;[,},]*|,1,2,3,4,I;5,6,7,'>#>;>S>8,^,9,0,^,8,a,y;b,m>A;Q>/,c,d,", "P&{=#-^=m@i-e,}$P;C>*, %=,h;f,g,-,h,i,j,0>a>k,5;l,m,n,o,7,p,m>k>V>8,q,9,9,q,],*>a,y;l>g>p,Q>/,(,"}; searchandrescue_1.5.0/sar/icons/SearchAndRescue2.xpm0000644000175000017500000007466110104532745021470 0ustar jessejesse/* XPM */ static char * SearchAndRescue2_xpm[] = { "48 48 1643 2", " c None", ". c #828FB8", "+ c #8592B6", "@ c #8390B7", "# c #7D8CB3", "$ c #7D8BB4", "% c #7E8DB5", "& c #838AB3", "* c #858CB3", "= c #848BB3", "- c #868DB3", "; c #7E8DB3", "> c #7E8EB3", ", c #7D8EB3", "' c #7D8DB3", ") c #7C8DB3", "! c #7F8EB3", "~ c #7F90B3", "{ c #8192B4", "] c #8293B4", "^ c #8F96B6", "/ c #949BB9", "( c #969CBB", "_ c #939AB9", ": c #8E95B6", "< c #8C93B5", "[ c #8798B7", "} c #8797B7", "| c #9097B7", "1 c #939ABA", "2 c #9198B8", "3 c #8290B8", "4 c #8490B6", "5 c #808EB5", "6 c #7B8AB2", "7 c #7B89B2", "8 c #7B8AB3", "9 c #7E89B2", "0 c #848BB2", "a c #8995B6", "b c #8C98B8", "c c #9298B8", "d c #8F96B7", "e c #8A91B4", "f c #8591B4", "g c #8D94B6", "h c #8A96B7", "i c #8B92B5", "j c #8F96B8", "k c #9198B9", "l c #9299B9", "m c #8391B8", "n c #838EB7", "o c #7988B1", "p c #7A88B1", "q c #7987B1", "r c #838AB2", "s c #8494B6", "t c #8596B7", "u c #878EB3", "v c #7E8FB3", "w c #8C93B6", "x c #8D95B7", "y c #8B93B6", "z c #8990B5", "A c #8990B4", "B c #8B92B6", "C c #8E95B7", "D c #838FB6", "E c #818DB5", "F c #7988B0", "G c #7987B0", "H c #7886B0", "I c #7786AF", "J c #8087B0", "K c #8289B1", "L c #848BB1", "M c #818CB2", "N c #818DB2", "O c #7D8DB2", "P c #7C8DB2", "Q c #7F8FB3", "R c #8090B3", "S c #8291B5", "T c #8292B5", "U c #8190B4", "V c #8692B5", "W c #8990B3", "X c #868DB2", "Y c #828EB3", "Z c #8893B6", "` c #888FB4", " . c #8A91B5", ".. c #8E95B8", "+. c #838DB5", "@. c #7F8DB2", "#. c #7886AF", "$. c #7584AD", "%. c #7E85AE", "&. c #8188B0", "*. c #838AB0", "=. c #848CB1", "-. c #8391B6", ";. c #808EB4", ">. c #7E8DB2", ",. c #868EB3", "'. c #858CB2", "). c #8493B6", "!. c #8392B5", "~. c #8C93B7", "{. c #838EB4", "]. c #7A88B0", "^. c #7685AD", "/. c #7E85AD", "(. c #8087AE", "_. c #8289AF", ":. c #848BB0", "<. c #7C8CB1", "[. c #7C8BB1", "}. c #808CB1", "|. c #808CB2", "1. c #828DB2", "2. c #828EB2", "3. c #818DB3", "4. c #7E8CB3", "5. c #808EB3", "6. c #8390B6", "7. c #828FB5", "8. c #7D8CB2", "9. c #7E89B1", "0. c #828CB3", "a. c #818FB3", "b. c #808AB1", "c. c #838AB1", "d. c #8990B6", "e. c #8390B4", "f. c #7B89B0", "g. c #7B88B0", "h. c #7A89B0", "i. c #7888AE", "j. c #7F86AD", "k. c #8188AE", "l. c #7B8BB0", "m. c #7C8AB0", "n. c #858CB0", "o. c #868DB1", "p. c #7D8BB3", "q. c #7C8AB2", "r. c #7D8AB3", "s. c #7D8BB2", "t. c #7F8DB3", "u. c #8290B5", "v. c #828DB4", "w. c #7C8BB2", "x. c #7B8BB1", "y. c #7887B0", "z. c #7E8AB2", "A. c #858CB4", "B. c #8D94B8", "C. c #8A91B8", "D. c #8289B0", "E. c #8188AF", "F. c #8087AD", "G. c #838AAF", "H. c #7D89B3", "I. c #7C89B3", "J. c #7F8CB3", "K. c #818FB5", "L. c #8289B5", "M. c #7B89B3", "N. c #7A87B2", "O. c #7782B2", "P. c #7B84B4", "Q. c #818DB6", "R. c #8389B2", "S. c #7D84B0", "T. c #7784B0", "U. c #8187B2", "V. c #8288B3", "W. c #8590B5", "X. c #8E95B9", "Y. c #8F96BB", "Z. c #888FB5", "`. c #8087AF", " + c #7F86AF", ".+ c #8289B2", "++ c #8188B2", "@+ c #7C8AB9", "#+ c #7C89B9", "$+ c #7F8CB4", "%+ c #808BB5", "&+ c #7F8CB5", "*+ c #7F8BB4", "=+ c #8289B3", "-+ c #7C85B3", ";+ c #7D84B4", ">+ c #868DB7", ",+ c #868DB5", "'+ c #7C83B1", ")+ c #8087B2", "!+ c #8288B4", "~+ c #7F86B3", "{+ c #8188B4", "]+ c #888EB9", "^+ c #8D93BC", "/+ c #878EB6", "(+ c #868DB4", "_+ c #858CB5", ":+ c #848BB4", "<+ c #8188B3", "[+ c #8289B4", "}+ c #8289B6", "|+ c #8188B6", "1+ c #848BB6", "2+ c #838AB4", "3+ c #7E8AB5", "4+ c #7D8ABC", "5+ c #7E89BB", "6+ c #7E89B5", "7+ c #7D89BC", "8+ c #7D88BC", "9+ c #808CB6", "0+ c #828FB7", "a+ c #828EB7", "b+ c #878EB7", "c+ c #878FB7", "d+ c #848EB7", "e+ c #8990B9", "f+ c #888FB8", "g+ c #848CB6", "h+ c #7F8BB5", "i+ c #868CB9", "j+ c #888FB9", "k+ c #8A90B7", "l+ c #878EBA", "m+ c #868DB9", "n+ c #848BB8", "o+ c #8289B7", "p+ c #8188B7", "q+ c #8087B6", "r+ c #8088BA", "s+ c #838AB7", "t+ c #808ABA", "u+ c #838AB6", "v+ c #7D88B6", "w+ c #7E88B7", "x+ c #7F89B8", "y+ c #808AB9", "z+ c #7F8BBD", "A+ c #808CBC", "B+ c #828BBA", "C+ c #828ABB", "D+ c #808BBB", "E+ c #818DBC", "F+ c #828FBA", "G+ c #838EB8", "H+ c #838DB8", "I+ c #848DB8", "J+ c #8B92BA", "K+ c #8C93BA", "L+ c #828FB9", "M+ c #8D94BB", "N+ c #8D93BB", "O+ c #8F96BF", "P+ c #8D94C0", "Q+ c #8A90BC", "R+ c #858CBB", "S+ c #848BB9", "T+ c #8188B8", "U+ c #8087B7", "V+ c #838ABA", "W+ c #8289BA", "X+ c #7F88B9", "Y+ c #7F89BA", "Z+ c #818BBB", "`+ c #818BBC", " @ c #818BBD", ".@ c #808ABC", "+@ c #7E87BA", "@@ c #7D86BB", "#@ c #7D87BB", "$@ c #7E88BB", "%@ c #7F8BBB", "&@ c #7F89BB", "*@ c #7F8AB6", "=@ c #8089B6", "-@ c #858EB9", ";@ c #8890B8", ">@ c #828CB8", ",@ c #8892BB", "'@ c #98A0C5", ")@ c #97A0C4", "!@ c #9BA3C5", "~@ c #989FC5", "{@ c #929CC1", "]@ c #8A94BC", "^@ c #878FBB", "/@ c #848EB8", "(@ c #8087B8", "_@ c #8087B9", ":@ c #7E88B9", "<@ c #7F89B9", "[@ c #8089B9", "}@ c #7E89BA", "|@ c #828AB8", "1@ c #808BBD", "2@ c #7E8BBC", "3@ c #7E8ABC", "4@ c #808BB6", "5@ c #818CBD", "6@ c #808CB7", "7@ c #818AB6", "8@ c #7F89B6", "9@ c #7F8BB7", "0@ c #868EBB", "a@ c #8288BC", "b@ c #858DBE", "c@ c #8890BB", "d@ c #8791BC", "e@ c #868EBC", "f@ c #838FB8", "g@ c #A3ACCD", "h@ c #A5ABCD", "i@ c #A3A9CA", "j@ c #9EA5C6", "k@ c #98A0C4", "l@ c #929ABC", "m@ c #8992BA", "n@ c #858EB8", "o@ c #8289B8", "p@ c #8087BA", "q@ c #8188BA", "r@ c #8289B9", "s@ c #7D88B9", "t@ c #8188B5", "u@ c #7F86B7", "v@ c #7F86BA", "w@ c #7D86BA", "x@ c #7D87BC", "y@ c #7C89BC", "z@ c #7C86BD", "A@ c #7C87B8", "B@ c #7B88B6", "C@ c #7E89B6", "D@ c #7E87B6", "E@ c #848BBE", "F@ c #7F86BD", "G@ c #8289BF", "H@ c #878EBB", "I@ c #868CBA", "J@ c #8A91B9", "K@ c #A6ADD4", "L@ c #AEB3D5", "M@ c #A9AFD1", "N@ c #A2A8CD", "O@ c #9DA3C8", "P@ c #939AC3", "Q@ c #8B92BF", "R@ c #868DBC", "S@ c #838ABB", "T@ c #848BBA", "U@ c #535879", "V@ c #7F86B9", "W@ c #7C83BB", "X@ c #7B82BD", "Y@ c #7D84BC", "Z@ c #7E85BD", "`@ c #8188BF", " # c #8388BE", ".# c #8289BD", "+# c #848ABE", "@# c #848BBD", "## c #848ABF", "$# c #878EBF", "%# c #858CBD", "&# c #858CBF", "*# c #8990BF", "=# c #ABB0D5", "-# c #ACB1D5", ";# c #A9AECF", "># c #A3A9CF", ",# c #9EA4CB", "'# c #959BC4", ")# c #8C93C0", "!# c #8990BE", "~# c #878EBD", "{# c #6B6F97", "]# c #696F94", "^# c #5E6485", "/# c #4A4F6D", "(# c #121422", "_# c #202030", ":# c #848BBB", "<# c #8289BB", "[# c #8087BB", "}# c #7D84BB", "|# c #7C83BA", "1# c #7D84BA", "2# c #8188BD", "3# c #8389BE", "4# c #878CC0", "5# c #878EC0", "6# c #848AC1", "7# c #8990C0", "8# c #8E95C4", "9# c #969DC5", "0# c #9198C5", "a# c #8E94C6", "b# c #9298C4", "c# c #AFB6D4", "d# c #ADB3D6", "e# c #A7ACD0", "f# c #A4AAD0", "g# c #9BA1C8", "h# c #949AC3", "i# c #8E95C3", "j# c #7A81A8", "k# c #7B82AB", "l# c #757CA4", "m# c #6C7096", "n# c #6A7094", "o# c #696F93", "p# c #575C79", "q# c #141622", "r# c #0D0D18", "s# c #494B67", "t# c #858CBC", "u# c #868DBD", "v# c #838ABC", "w# c #848BBC", "x# c #7F86BC", "y# c #8087BC", "z# c #8289BE", "A# c #878EC1", "B# c #878EC2", "C# c #8A90C3", "D# c #8C93C2", "E# c #8B92C4", "F# c #8C92C3", "G# c #8A91C2", "H# c #969DC7", "I# c #9EA4C8", "J# c #989DCA", "K# c #959CC6", "L# c #979BC8", "M# c #B3B7D7", "N# c #B0B8D7", "O# c #ADB4D7", "P# c #A4ACD1", "Q# c #9DA3C9", "R# c #9399C3", "S# c #8E95C0", "T# c #8087B1", "U# c #7B82A9", "V# c #7C82AA", "W# c #777EA8", "X# c #70749A", "Y# c #6B7193", "Z# c #696E91", "`# c #555B76", " $ c #08090F", ".$ c #080911", "+$ c #7E85BC", "@$ c #8087BD", "#$ c #868DC0", "$$ c #8990C2", "%$ c #888FC2", "&$ c #898FC2", "*$ c #8B91C3", "=$ c #8E95C5", "-$ c #9097C4", ";$ c #939AC4", ">$ c #949BC4", ",$ c #9198C4", "'$ c #969DC6", ")$ c #989FC6", "!$ c #959CC5", "~$ c #99A0C7", "{$ c #B8BDD9", "]$ c #B4BAD7", "^$ c #AFB7D4", "/$ c #A8AFD1", "($ c #A2A9CB", "_$ c #999EC7", ":$ c #9399C1", "<$ c #8E95C2", "[$ c #8D94C1", "}$ c #8B92BE", "|$ c #7E84AD", "1$ c #787DA6", "2$ c #6D7498", "3$ c #6A7193", "4$ c #646886", "5$ c #535772", "6$ c #0A0A0F", "7$ c #07070B", "8$ c #888FBD", "9$ c #8990BD", "0$ c #8289BC", "a$ c #838ABE", "b$ c #8A91C1", "c$ c #8B92C1", "d$ c #8D94C3", "e$ c #8F96C5", "f$ c #9299C4", "g$ c #9097C5", "h$ c #959DC5", "i$ c #979EC5", "j$ c #989EC6", "k$ c #9A9FC8", "l$ c #9CA1C8", "m$ c #9DA2C7", "n$ c #B8BFDD", "o$ c #B5BCDA", "p$ c #ABB1D0", "q$ c #A8B0D0", "r$ c #A7AED1", "s$ c #A4AACD", "t$ c #9AA0C5", "u$ c #959BC6", "v$ c #8E95C1", "w$ c #7D83AB", "x$ c #7B81A9", "y$ c #6C7392", "z$ c #6C7090", "A$ c #60647E", "B$ c #373B4B", "C$ c #09090C", "D$ c #575B79", "E$ c #8A91BE", "F$ c #8B92BD", "G$ c #8A91BD", "H$ c #888FBC", "I$ c #858CBE", "J$ c #8990C1", "K$ c #8D94C2", "L$ c #9097C2", "M$ c #939AC5", "N$ c #949CC3", "O$ c #979DC5", "P$ c #949CC7", "Q$ c #9DA3C7", "R$ c #A0A6CA", "S$ c #A3AAC9", "T$ c #A9ACC9", "U$ c #B2B6D7", "V$ c #AFB3DA", "W$ c #B1B7D5", "X$ c #AEB5D6", "Y$ c #B0B5D3", "Z$ c #A8ADD1", "`$ c #9EA5CC", " % c #9CA2C9", ".% c #989DC9", "+% c #9096C2", "@% c #9097C3", "#% c #8890B7", "$% c #8086AD", "%% c #74799B", "&% c #6A6D8A", "*% c #5B5F74", "=% c #0A0A0D", "-% c #0C0C0D", ";% c #8F96C2", ">% c #8D94BF", ",% c #8A91BF", "'% c #8C93BF", ")% c #8C93C1", "!% c #9198C2", "~% c #949BC5", "{% c #939AC2", "]% c #9CA1C6", "^% c #98A0C7", "/% c #9CA3C6", "(% c #9CA2C6", "_% c #A4A9C7", ":% c #A8ACCC", "<% c #B0B2D1", "[% c #AEB3D2", "}% c #B0B7D7", "|% c #B0B8D9", "1% c #B3B8DB", "2% c #B4BBD9", "3% c #AEB4D1", "4% c #A4A9CE", "5% c #A2AACB", "6% c #99A0C8", "7% c #969CC6", "8% c #949BC2", "9% c #9399C4", "0% c #9198C1", "a% c #7B81A4", "b% c #686F88", "c% c #505368", "d% c #0D0D0F", "e% c #0E0E0F", "f% c #9198C3", "g% c #8F96C1", "h% c #979DC6", "i% c #9399BC", "j% c #8E96B6", "k% c #8F96B5", "l% c #8B91AF", "m% c #8E92B1", "n% c #969CB3", "o% c #ADB1D2", "p% c #B2B7D6", "q% c #B5BAD3", "r% c #ACB2D5", "s% c #B2B8D8", "t% c #B9BEDC", "u% c #B3B9D6", "v% c #A6ACCE", "w% c #A1A9CE", "x% c #9FA7C8", "y% c #9BA3C8", "z% c #98A0C6", "A% c #979FC4", "B% c #959DC4", "C% c #949BC3", "D% c #8D94BC", "E% c #7F84AA", "F% c #6A6F87", "G% c #3D4150", "H% c #141414", "I% c #9299C3", "J% c #9096BD", "K% c #868CB2", "L% c #8086AB", "M% c #737999", "N% c #747896", "O% c #797F9C", "P% c #6E7185", "Q% c #717488", "R% c #797C94", "S% c #6E7084", "T% c #717382", "U% c #737584", "V% c #B9BBD6", "W% c #B8BBD5", "X% c #A8ABCE", "Y% c #ACB2CE", "Z% c #B2B6D6", "`% c #B2B7D9", " & c #B1B5D5", ".& c #AAB1CF", "+& c #AAB0D0", "@& c #AAAECF", "#& c #A3ABCD", "$& c #A0A8C8", "%& c #9DA4CA", "&& c #9EA5C8", "*& c #9AA2C9", "=& c #98A0C8", "-& c #9AA2C5", ";& c #717493", ">& c #19191B", ",& c #1A1A1D", "'& c #8F96C0", ")& c #747A9B", "!& c #6B6F8A", "~& c #55596F", "{& c #434657", "]& c #3C3F4F", "^& c #3F4151", "/& c #424657", "(& c #2D2F38", "_& c #202028", ":& c #121213", "<& c #1E1F20", "[& c #323334", "}& c #3A3A3F", "|& c #666872", "1& c #87899F", "2& c #AAADCF", "3& c #AEB2D1", "4& c #B5B9D4", "5& c #B3B7D1", "6& c #B2B4D1", "7& c #B4B7D4", "8& c #AFB3D3", "9& c #ADB2D0", "0& c #AAB1D1", "a& c #A8AECF", "b& c #A4AACE", "c& c #A6ABCD", "d& c #A0A7CC", "e& c #9FA6CA", "f& c #9DA5C9", "g& c #9BA2C9", "h& c #9AA2C6", "i& c #979EC3", "j& c #585C77", "k& c #1B1B1E", "l& c #36393C", "m& c #9098BE", "n& c #0C0C0E", "o& c #090909", "p& c #0B0B0C", "q& c #333543", "r& c #5B5E74", "s& c #949CC4", "t& c #989EC5", "u& c #9AA0C7", "v& c #9DA4C7", "w& c #A3A6CC", "x& c #A4AAD1", "y& c #ABAFD0", "z& c #B1B4D3", "A& c #B8BCD3", "B& c #BBBFD2", "C& c #B6BBCB", "D& c #AAAED1", "E& c #AFB2CF", "F& c #B2B3D1", "G& c #ACB2CF", "H& c #AEB2CD", "I& c #A9B0D1", "J& c #ADB1CF", "K& c #ACB3D0", "L& c #AAB0CE", "M& c #A8AECC", "N& c #A5A9CC", "O& c #A0A7CA", "P& c #9FA6C8", "Q& c #9BA3CA", "R& c #74788C", "S& c #40424D", "T& c #1C1C1D", "U& c #1E1E1F", "V& c #272B2A", "W& c #41454D", "X& c #717489", "Y& c #1B1B1D", "Z& c #171717", "`& c #131313", " * c #080808", ".* c #050505", "+* c #080909", "@* c #9299C1", "#* c #929AC4", "$* c #969DC3", "%* c #99A0C6", "&* c #9EA3C9", "** c #A3A9C8", "=* c #A8ACD0", "-* c #B0B4D1", ";* c #B1B8D6", ">* c #B6BED8", ",* c #BCC0D4", "'* c #B9BED1", ")* c #B1B8CB", "!* c #B4B6D2", "~* c #B3B5CE", "{* c #B5B7D0", "]* c #B5B7CE", "^* c #878B9E", "/* c #4D4E53", "(* c #464648", "_* c #454648", ":* c #414145", "<* c #39393A", "[* c #42434B", "}* c #565967", "|* c #777B8F", "1* c #8488A5", "2* c #9094B5", "3* c #959CBF", "4* c #9BA2C8", "5* c #858286", "6* c #999898", "7* c #1F1F20", "8* c #5B1E1F", "9* c #581A1B", "0* c #151616", "a* c #0D0D0E", "b* c #500809", "c* c #040404", "d* c #060606", "e* c #291C20", "f* c #B4A7AC", "g* c #9299C2", "h* c #9199C1", "i* c #959CC3", "j* c #9EA3C8", "k* c #A1A4CB", "l* c #A6AACB", "m* c #A9ADCC", "n* c #ACAFCE", "o* c #B0B6CE", "p* c #B6BDD4", "q* c #C0C4D6", "r* c #B8BDCF", "s* c #B3B7CB", "t* c #B6B9D5", "u* c #B6B9D2", "v* c #B6B8D2", "w* c #ABAFC0", "x* c #A7ABBD", "y* c #A1A6BC", "z* c #969BB1", "A* c #9AA1BB", "B* c #9AA0B9", "C* c #9598B3", "D* c #9FA7BE", "E* c #9CA4C0", "F* c #9CA2C0", "G* c #9BA3BF", "H* c #9CA3C0", "I* c #9EA4BF", "J* c #9EA5BF", "K* c #717476", "L* c #696A6A", "M* c #494B4B", "N* c #69676D", "O* c #615C5B", "P* c #4D1719", "Q* c #551111", "R* c #520A0B", "S* c #090908", "T* c #0B0B0B", "U* c #0D0E0F", "V* c #111112", "W* c #141416", "X* c #161719", "Y* c #161717", "Z* c #949CBC", "`* c #999EBC", " = c #A0A3C1", ".= c #A1A6C3", "+= c #A4A8C4", "@= c #A8AEC9", "#= c #AEB3CE", "$= c #AFB3CE", "%= c #B4B9CE", "&= c #BABDD5", "*= c #BEC3D9", "== c #BFC7D6", "-= c #BABED0", ";= c #B6BCCE", ">= c #BEC0D9", ",= c #BABDD7", "'= c #B7BAD2", ")= c #B9BDD6", "!= c #B3B5CF", "~= c #ADB1CB", "{= c #A5ABC4", "]= c #A5ABC5", "^= c #A2A8C6", "/= c #A2A8C2", "(= c #A5A9C5", "_= c #A3A8C2", ":= c #9CA4BF", "<= c #9EA5C1", "[= c #9FA6C3", "}= c #76787D", "|= c #797B7C", "1= c #707271", "2= c #1D1D20", "3= c #5C5C5F", "4= c #5D5C60", "5= c #521113", "6= c #4E0D0E", "7= c #430808", "8= c #0A0A09", "9= c #262623", "0= c #3C3C37", "a= c #2E2E2C", "b= c #1A1A1B", "c= c #181919", "d= c #212225", "e= c #303030", "f= c #2C2C2D", "g= c #9EA3BE", "h= c #A4A8C5", "i= c #AAAFCB", "j= c #ACB0CA", "k= c #AEB0C9", "l= c #AEB2CA", "m= c #B0B5D0", "n= c #B3B6D0", "o= c #BABFD3", "p= c #C0C4DA", "q= c #C0C7DB", "r= c #C2C8D9", "s= c #BAC0D1", "t= c #B8BECE", "u= c #BEC1D9", "v= c #B8BAD6", "w= c #B5B9D1", "x= c #B9BAD0", "y= c #B9BBD1", "z= c #B9BBD4", "A= c #AEB4CA", "B= c #A7AEC2", "C= c #A3ACC4", "D= c #A2A8C0", "E= c #A4ACC2", "F= c #A3ADC4", "G= c #A0AAC2", "H= c #A0A9C1", "I= c #9BA7C0", "J= c #9EA7C2", "K= c #747679", "L= c #727476", "M= c #242325", "N= c #1D1D1D", "O= c #363839", "P= c #531111", "Q= c #450D0E", "R= c #410A0A", "S= c #3B0A0A", "T= c #501D1B", "U= c #40403C", "V= c #2F302F", "W= c #333332", "X= c #2F2F31", "Y= c #272729", "Z= c #4C4C4D", "`= c #525252", " - c #5F5460", ".- c #AEB3C8", "+- c #B0B5C9", "@- c #B1B8D0", "#- c #B3B9D0", "$- c #B1B7CC", "%- c #B7BBD2", "&- c #B4BAD5", "*- c #B6BBD3", "=- c #BEC4D7", "-- c #C3C8D8", ";- c #C8CCDA", ">- c #C6CDDD", ",- c #B7BDCE", "'- c #B2BBCE", ")- c #BBBDD5", "!- c #B5B9D5", "~- c #B5B9CF", "{- c #B2B5CE", "]- c #B2B5CC", "^- c #B2B7CF", "/- c #B2B7CD", "(- c #ADB1C8", "_- c #A5AFC8", ":- c #9EABC5", "<- c #6B717F", "[- c #5C616C", "}- c #9EA8C2", "|- c #A1ABC0", "1- c #707273", "2- c #29292A", "3- c #222227", "4- c #1C1D1E", "5- c #668967", "6- c #581212", "7- c #550F0F", "8- c #540F0E", "9- c #501513", "0- c #5F2F2D", "a- c #926A68", "b- c #A4827E", "c- c #663D3C", "d- c #424344", "e- c #38383C", "f- c #79797A", "g- c #525052", "h- c #ABB4CB", "i- c #B4BED2", "j- c #B4B9D1", "k- c #B8BED5", "l- c #B6BCD4", "m- c #B4BBD1", "n- c #BAC0D5", "o- c #B9BFD6", "p- c #B7BDD6", "q- c #BBC1D8", "r- c #BEC4DA", "s- c #C8CEDB", "t- c #BEC9DB", "u- c #B3BCCE", "v- c #B3BAC9", "w- c #B8BBD3", "x- c #B7BCD3", "y- c #B6B9D0", "z- c #B2B4CF", "A- c #AFB1CE", "B- c #AEB3C9", "C- c #AAB2C8", "D- c #AAAFC9", "E- c #AAAFC4", "F- c #A6AEC7", "G- c #A2ABC2", "H- c #42464B", "I- c #A1ACC2", "J- c #A2ABC3", "K- c #A4AEC4", "L- c #474444", "M- c #6B7275", "N- c #6F6F73", "O- c #242529", "P- c #1A1B1B", "Q- c #494B4A", "R- c #4E5150", "S- c #5B0F0F", "T- c #530F0F", "U- c #4E1111", "V- c #551B1C", "W- c #774443", "X- c #855050", "Y- c #884848", "Z- c #862C2B", "`- c #923C34", " ; c #B98380", ".; c #976C69", "+; c #B5BCD2", "@; c #B8BED3", "#; c #B8BDD4", "$; c #B9C2DA", "%; c #B6BFD1", "&; c #B4BDD3", "*; c #B6BBD1", "=; c #B5BBD2", "-; c #BBC4D3", ";; c #B9BFD3", ">; c #B9BFD1", ",; c #B5BAD1", "'; c #B0B8CD", "); c #ABB1C7", "!; c #B5BAD2", "~; c #B9BCD2", "{; c #B8BBD6", "]; c #B7BBD7", "^; c #B4BBD3", "/; c #B2B6CD", "(; c #A9B4CC", "_; c #AAB0C8", ":; c #A9B1C9", "<; c #A5AEC7", "[; c #A2ADC4", "}; c #4D5158", "|; c #A32929", "1; c #A4AFC6", "2; c #7C7D83", "3; c #7C7D84", "4; c #727477", "5; c #6E706F", "6; c #1A1A1C", "7; c #676968", "8; c #6E706E", "9; c #5C1112", "0; c #571214", "a; c #231919", "b; c #232425", "c; c #833730", "d; c #933E36", "e; c #9D423C", "f; c #BABBC2", "g; c #999A9C", "h; c #BEC4D6", "i; c #B9C0D5", "j; c #B6BED3", "k; c #BBC5D6", "l; c #BDC6D9", "m; c #BBC4D7", "n; c #B1B8D2", "o; c #ACB3CA", "p; c #ACB6CC", "q; c #ACB1CA", "r; c #B0B6CC", "s; c #B7BDD0", "t; c #B6BCD2", "u; c #B0B7D4", "v; c #BEC2DA", "w; c #BAC0D7", "x; c #BBC0D8", "y; c #B4BAD2", "z; c #ADB4CF", "A; c #AEB5CF", "B; c #AAAFC8", "C; c #7A8190", "D; c #7E8699", "E; c #642929", "F; c #A8B1C4", "G; c #7F8184", "H; c #747777", "I; c #85878B", "J; c #868689", "K; c #85878A", "L; c #28282A", "M; c #797679", "N; c #393C39", "O; c #363530", "P; c #525553", "Q; c #777879", "R; c #898A89", "S; c #9E9DA2", "T; c #C0BDC1", "U; c #A2A4A5", "V; c #909195", "W; c #6B6E6E", "X; c #BDC3D7", "Y; c #B7BED5", "Z; c #B4BED3", "`; c #B9C1D3", " > c #B5BDD4", ".> c #BAC0D6", "+> c #B1B9D0", "@> c #ADB4C9", "#> c #ABB1C8", "$> c #A8AFC8", "%> c #A7AEC7", "&> c #A8AEC6", "*> c #AFB5CA", "=> c #B9C1CF", "-> c #B5BECF", ";> c #C5CEE2", ">> c #D2D7EB", ",> c #B4B7CC", "'> c #B4BAD3", ")> c #BABED7", "!> c #B9BCD8", "~> c #BFC3DA", "{> c #BBC4DA", "]> c #B6BDD5", "^> c #B8BED4", "/> c #BAC1D9", "(> c #B7C1D8", "_> c #767984", ":> c #6F692E", "<> c #7F7F84", "[> c #7E8084", "}> c #838585", "|> c #808084", "1> c #7B7A7B", "2> c #848689", "3> c #6A686A", "4> c #8A878A", "5> c #848584", "6> c #7C7B80", "7> c #929494", "8> c #9B9C9D", "9> c #7A7C7D", "0> c #8D9092", "a> c #B5BBD1", "b> c #686B6D", "c> c #BFC6DE", "d> c #B4BCD3", "e> c #ADB3CE", "f> c #ABB1CD", "g> c #ACB4CA", "h> c #A8AEC5", "i> c #A8ADC7", "j> c #A6AEC9", "k> c #AEB6CB", "l> c #C5CCDC", "m> c #C2C4DC", "n> c #C4C7D9", "o> c #C6C8D9", "p> c #B9BACF", "q> c #B2B4C9", "r> c #B6B8CE", "s> c #B7B9D1", "t> c #BDBFD5", "u> c #BFC1D2", "v> c #BABCD2", "w> c #BCBED3", "x> c #9E6C6D", "y> c #A67072", "z> c #8E5357", "A> c #5A3336", "B> c #4C3234", "C> c #3C3C4E", "D> c #7E7E86", "E> c #804144", "F> c #787A79", "G> c #474649", "H> c #967979", "I> c #8B8A8E", "J> c #9E9F9E", "K> c #B6B8B6", "L> c #BCBDD1", "M> c #ABACC6", "N> c #ADAFC6", "O> c #AAACC5", "P> c #B0B3C7", "Q> c #B3B5C9", "R> c #B4B6CD", "S> c #B7B9D2", "T> c #B8BAD3", "U> c #B7B8D2", "V> c #AFB1C9", "W> c #AAADC8", "X> c #ACAEC4", "Y> c #AAACC3", "Z> c #A8A9C4", "`> c #BEBFD3", " , c #B8BACF", "., c #B9BBD0", "+, c #BDBECF", "@, c #BFC1D6", "#, c #C3C4D7", "$, c #BEC0D4", "%, c #B8B9CF", "&, c #C0C1D8", "*, c #B6B9CF", "=, c #B2B4C8", "-, c #BDBED1", ";, c #B9BCD0", ">, c #BCBED2", ",, c #A37371", "', c #AD7A79", "), c #995F61", "!, c #7F4849", "~, c #838587", "{, c #8D8C90", "], c #918F96", "^, c #915450", "/, c #995A52", "(, c #424246", "_, c #39393C", ":, c #ACAEC7", "<, c #ADAFC9", "[, c #B8B9D0", "}, c #B0B2C9", "|, c #AFB0C8", "1, c #AEB1C6", "2, c #AEB1CA", "3, c #AFB0C9", "4, c #ADB0C6", "5, c #ACAFC6", "6, c #ACAFC7", "7, c #A8AAC2", "8, c #A9AABF", "9, c #A9ACC2", "0, c #A7A8C3", "a, c #A7AAC2", "b, c #A6A8C2", "c, c #ABADC4", "d, c #BBBDD4", "e, c #BBBED3", "f, c #AFB1CA", "g, c #B6B7CD", "h, c #B1B2CA", "i, c #B4B6CC", "j, c #B2B4CA", "k, c #B1B4C9", "l, c #BABCD3", "m, c #B4B5CD", "n, c #B0B3C6", "o, c #AFB1C6", "p, c #B3B4CA", "q, c #B4B6CA", "r, c #B2B4CB", "s, c #B9BBCF", "t, c #C0C2D6", "u, c #BEBFD6", "v, c #BABBD1", "w, c #A26862", "x, c #AD716C", "y, c #B2786D", "z, c #B2B3C8", "A, c #AEB0C6", "B, c #ABADC3", "C, c #B0B2C8", "D, c #B5B8CF", "E, c #AEAFC6", "F, c #ABAEC7", "G, c #AEB1C3", "H, c #AEB0C8", "I, c #AEB0C7", "J, c #AAADC6", "K, c #A6A9C2", "L, c #A0A1BD", "M, c #A3A4BF", "N, c #A6A8C0", "O, c #A7A9C3", "P, c #A8AAC4", "Q, c #ACADC5", "R, c #A8ABC5", "S, c #AAACC4", "T, c #AEB0CA", "U, c #AFB1C7", "V, c #B4B7CD", "W, c #B3B4C9", "X, c #B2B3CB", "Y, c #B1B3CF", "Z, c #ADB0C9", "`, c #B1B2CB", " ' c #BCBBD4", ".' c #B3B5CD", "+' c #ABAEC9", "@' c #ABACC4", "#' c #AAACC2", "$' c #B0B1CA", "%' c #B1B4CF", "&' c #B8BACE", "*' c #B9BBD2", "=' c #BBBCD4", "-' c #BABCD4", ";' c #B7B8D0", ">' c #B3B6CD", ",' c #AEB1C9", "'' c #B0B3C8", ")' c #A9AAC2", "!' c #A9ABC5", "~' c #ACAECA", "{' c #B1B3CD", "]' c #B1B2CC", "^' c #BABDD4", "/' c #B7BAD1", "(' c #A9ABC2", "_' c #A2A3BC", ":' c #A5A7C1", "<' c #A4A6BF", "[' c #A5A6BE", "}' c #A7A9C2", "|' c #A8AAC3", "1' c #A2A4BF", "2' c #A2A3BF", "3' c #A2A4BE", "4' c #A8ABC0", "5' c #B0B2C6", "6' c #A9AAC1", "7' c #AEAFC5", "8' c #B2B4CC", "9' c #B0B1C9", "0' c #B6B8CD", "a' c #AFB1CB", "b' c #B2B3CC", "c' c #B5B6CA", "d' c #BABBCE", "e' c #AFB0CA", "f' c #ADAFCA", "g' c #A7AAC3", "h' c #A4A6C3", "i' c #A4A7C1", "j' c #A8AAC1", "k' c #B3B5CC", "l' c #B5B7CC", "m' c #B2B4C5", "n' c #ABADC7", "o' c #AFB1C8", "p' c #B8BAD2", "q' c #B7B9D3", "r' c #ABACC3", "s' c #ABAEC5", "t' c #B6B7D1", "u' c #B3B5D0", "v' c #B5B7D5", "w' c #B9BAD2", "x' c #B7B9D0", "y' c #C1C2D8", "z' c #B6B8D1", "A' c #A3A6BF", "B' c #A6A7C2", "C' c #A5A8C1", "D' c #A2A3BE", "E' c #A0A2BD", "F' c #A8A9C1", "G' c #A7A9C1", "H' c #AFB0C6", "I' c #B5B7CD", "J' c #B8B9CD", "K' c #B7BAD4", "L' c #B3B5CA", "M' c #B2B3CA", "N' c #B4B5D0", "O' c #B9BAD6", "P' c #BEBFD7", "Q' c #BFC0D9", "R' c #ACADC7", "S' c #ACAECB", "T' c #A9ACC8", "U' c #A1A3BF", "V' c #A7AAC4", "W' c #A7AAC1", "X' c #A9AAC3", "Y' c #AAABC3", "Z' c #A3A5BE", "`' c #ABADC5", " ) c #A9AAC4", ".) c #B0B3CB", "+) c #B3B5CB", "@) c #B1B3CB", "#) c #B4B6CF", "$) c #BABDD2", "%) c #A4A5C1", "&) c #9FA1BD", "*) c #9E9FBC", "=) c #9D9EBA", "-) c #9C9DB9", ";) c #A0A1BC", ">) c #A7A8C5", ",) c #A7A8C4", "') c #ADAFC5", ")) c #B4B7CE", "!) c #ABACC5", "~) c #B5B7CF", "{) c #B9BBD3", "]) c #AAACC6", "^) c #A8AAC5", "/) c #A2A5C0", "() c #A3A6C1", "_) c #A1A3BE", ":) c #9FA0BA", "<) c #9EA0BB", "[) c #9D9EB9", "}) c #9D9FB9", "|) c #9EA0B9", "1) c #A4A5BE", "2) c #A8A9C3", "3) c #A9ABC4", "4) c #A9ABC3", "5) c #A3A5C0", "6) c #9EA0BC", "7) c #9E9FBA", "8) c #A5A6C0", "9) c #B0B1CC", "0) c #AEAFC9", "a) c #B0B0C8", "b) c #A7A8C1", "c) c #ADAFC7", "d) c #A3A4BE", "e) c #A4A5C0", "f) c #A5A7C2", "g) c #A0A2BC", "h) c #9B9DB8", "i) c #9A9BB7", "j) c #9B9CB8", "k) c #A1A3BD", "l) c #9FA0BD", "m) c #A1A2BE", "n) c #A1A2BF", "o) c #A0A1BE", "p) c #9FA0BB", "q) c #9D9FBB", "r) c #9B9FB9", "s) c #9CA0B9", "t) c #A0A4BD", "u) c #A5A8BE", "v) c #A9ADC3", "w) c #AFB3C8", "x) c #ADB0C7", "y) c #ABAFC7", "z) c #A8A7BC", "A) c #ABAABF", "B) c #AFADC2", "C) c #AEACC1", "D) c #A8A6BD", "E) c #A7A7BD", "F) c #A9A8BF", "G) c #ABABC0", "H) c #A8A8BE", "I) c #A3A3BC", "J) c #A4A4BD", "K) c #A4A4BC", "L) c #A6A6BE", "M) c #A7A7C0", "N) c #A5A5BF", "O) c #A5A6BF", "P) c #A6A6BF", "Q) c #A4A5BD", "R) c #A1A2BA", "S) c #9E9EB7", "T) c #9D9CB6", "U) c #9D9DB6", "V) c #A3A3BB", "W) c #A0A1BA", "X) c #A0A0B9", "Y) c #A1A1BB", "Z) c #A5A5BE", "`) c #A4A3BC", " ! c #A2A2BB", ".! c #A1A1B9", "+! c #9EA1B6", "@! c #9FA2B7", "#! c #A3A5BA", "$! c #A6A8BB", "%! c #A9ACBE", "&! c #ACAEC1", "*! c #AEB0C2", "=! c #AEB0C4", "-! c #ADAFC2", ";! c #ACAEC2", ">! c #A8A4B7", ",! c #ABA8BB", "'! c #AEAABD", ")! c #A9A5B9", "!! c #A7A5B7", "~! c #A9A6B9", "{! c #A9A7BA", "]! c #A8A6B8", "^! c #A6A4BA", "/! c #A5A5BB", "(! c #A6A5BC", "_! c #A6A5BB", ":! c #A8A7BD", "~ c #8A8EA3", ",~ c #888DA2", "'~ c #898EA3", ")~ c #888EA2", "!~ c #858A9E", "~~ c #83899D", "{~ c #82879C", "]~ c #81859A", "^~ c #7F8499", "/~ c #7F8599", "(~ c #80859A", "_~ c #82889C", ":~ c #83889C", "<~ c #868B9F", "[~ c #878CA0", "}~ c #85899D", "|~ c #84899C", "1~ c #848A9B", "2~ c #848B9B", "3~ c #878D9D", "4~ c #888F9E", "5~ c #8A91A0", "6~ c #8C93A1", "7~ c #8D93A2", "8~ c #8F95A4", "9~ c #8D94A3", "0~ c #8B92A1", "a~ c #8C93A3", "b~ c #667086", "c~ c #687288", "d~ c #6D7589", "e~ c #6E768B", "f~ c #6D768C", "g~ c #6D778D", "h~ c #71788E", "i~ c #73798F", "j~ c #727C91", "k~ c #717B90", "l~ c #727A8E", "m~ c #717A8E", "n~ c #727A8F", "o~ c #747C90", "p~ c #747D91", "q~ c #737C90", "r~ c #727C90", "s~ c #6E788C", "t~ c #6D778B", "u~ c #6C768A", "v~ c #6B7489", "w~ c #697287", "x~ c #697387", "y~ c #6A7388", "z~ c #6D778C", "A~ c #6E778B", "B~ c #6F788C", "C~ c #6F788D", "D~ c #70798D", "E~ c #6E798B", "F~ c #6E7A8B", "G~ c #717B8C", "H~ c #727D8E", "I~ c #758091", "J~ c #788393", "K~ c #798495", "L~ c #778394", "M~ c #768191", "N~ c #768193", ". + @ # $ % & * = - - ; > , , ; ' # ) ) ; ! ~ ~ ~ ~ ~ ~ ~ ~ { ] ^ / ( _ : < : [ } : : | 1 1 1 2 ", "3 4 5 6 7 8 9 0 = * - ' > , , ; ' # ) ) ; ! ~ ~ ~ ~ ~ ~ ~ ~ { ] a b c d e f g h a i i g j k l d ", "m n # o p q p r = * - ' > , , ; ' # ) ) ; ! ~ ~ ~ ~ ~ ~ ~ ~ { ] s t : < u v w x y z A B w j k C ", "D E 6 F G H I J K L L M N O P O > ; ; ; Q Q ~ Q Q Q Q Q R S T U U V e W X Y Z Z A u - ` A ...B ", "+.@.p F G #.$.%.&.*.*.=.=.O P O > ; ; ; Q Q ~ Q ! ! ! Q R -.T ;.>.,.X X '.,.).!.- '.r * - * ~.z ", "{.>.].F G #.^./.(._.*.:.:.<.[.}.|.1.1.1.2.2.> 3.4.4.4.; 5.6.7.4.8.'.}.}.9.0.-.a.b.b.c.'.'.* ~.d.", "e.>.f.g.h.].i./.j.k.:.*.*.l.m.n.L X o.o.o.X 8.0 p.q.r.s.t.u.v.w.w.L x.l.y.z.7.@.].f.n.'.L A.B.C.", "e '.*.D.D.*.E.(.F.j.F.F.(.k.G.:.'.- - - - * = p.p.H.I.r.J.K.L.p.p.H.M.N.O.P.Q.R.S.T.U.c.V.W.X.Y.", "Z.n.*.:.D.c.J &.`.`. +J &..+++.+K *.*.L '.* = = r.I.M.@+#+$+%+&+*+=+r.H.-+;+>+,+'+S.)+!+~+{+]+^+", "/+(+,+_+:+<+{+{+L.{+[+}+|+L.}+1+2+r 0 0 '.0 & 2+3+4+5+6+7+8+9+0+a+@ b+c+n d+e+f+1+,+/+g+h+[+1+i+", "j+k+e+l+m+n+o+o+p+q+p+r+o+p+s+t+u+u+1+1+1+1+u+L.v+w+x+y+z+x+A+B+C+D+D+E+F+G+H+I+f+J+K+3 L+I+l+M+", "N+O+O+P+Q+R+S+T+T+U+p+o+o+p+o+o+o+o+s+o+o+V+W+s+o+X+Y+Y+Z+`+ @.@+@@@#@$@%@&@*@=@n -@;@>@e+,@^+M+", "'@)@!@~@{@]@^@/@T+(@_@_@:@o+o+<@o+p+o+o+p+o+p+[@Y+p+p+U+Y+}@|@1@2@3@z+4@5@6@7@8@9@0@a@b@c@d@e@f@", "g@h@i@j@k@l@m@n@o@2+p@p@p@q@r@s@q@p+|+t@p+u@u@U+u@U+U+q@q@v@w@x@y@8+z@A@x@B@C@D@a@E@F@G@H@I@m+J@", "K@L@M@N@O@P@Q@R@S@T@r@q@V+W+T+U@q@q@q@q@_@v@V@_@p@V@r@q@p@p@v@W@X@Y@Y@Z@F@`@ #F@.#+#@###$#%#&#*#", "=#-#;#>#,#'#)#!#!#~#}+{#]#^#/#(#_#:#W+<#[#q@q@q@<#q@S@V+v@}#|#1#Y@2#.#3##5#6#E@#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#@#@#%#v#%#w#x#Y@x#y#z#&#A#B#C#D#E#F#G#D#D#H#I#J#K#L#", "M#N#O#P#Q#R#S#)#T#U#V#W#X#Y#Z#`# $.$~#~#u#%#u#%#u#~#@#y#x#+$@$F@`@#$$$%$&$*$=$-$;$>$,$'$)$)$!$~$", "{$]$^$/$($_$:$<$[$}$|$U#1$2$3$4$5$6$7$8$9$9$~#~#8$~#R@@#.#0$.#a$#$G#b$c$d$e$e$f$g$0#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$G$8$H$w#0$%#I$J$<$K$L$M$M$g$0#,$N$O$P$Q$R$S$T$", "U$V$W$X$Y$Z$`$ %.%R#+%+%@%#%$%%%&%*%=%-%L$;%L$v$>%Q@}$,%,%'%)%K$!%~%{%f$~%!$]%~$^%/%(%/%_%:%Z$<%", "[%}%|%1%2%3%4%5%6%7%!$8%9%f$0%0 a%b%c%d%e%{%f$@%f%f%g%v$g%@%L$;%>$h%~%P@,$j$Q$i%j%k%l%m%n%o%p%q%", "p$r%s%t%u%[%v%w%x%y%^%z%A%B%;$C%D%E%F%G%H%~%~%P@I%f%!%!%L$@%L$I%f$J%K%L%M%N%O%P%Q%R%S%T%U%Y$V%W%", "X%Y%Z%`% &.&+&@&#&$&%&&&*&=&-&7%u$~%k+;&>&,&i$>$P@I%f%'&R.)&!&~&{&]&^&/&(&_&:&<&[&}&|&1&2&3&4&5&", ".&6&7&8&8&9&0&@&a&b&c&d&e&f&g&h&z%h$i&7%'$j&k&l&m&,$n&o&o&p&q&r&,$I%P@s&s&t&u&v&w&x&;#y&z&A&B&C&", "D&E&F&G&H&I&J&K&L&M&N&d&O&P&Q&R&S&T&U&V&W&X&Y&Z&`&-% *.* *+*@*L$!%!%L$#*$*%*O@&***=*-*;*>*,*'*)*", "!*~*{*]*^*/*(*_*:*<*[*}*|*1*2*3*4*^%5*6*7*8*9*0*a*b*.*c*d*+*e*f*g*L$h*i*z%j*k*l*m*n*o*p*q*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*c*c*S*T*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=R=S=T=U=V=W=X=Y=Z=`= -.-+-@-#-$-%-&-*-=---;->-,-'-", ")-!-~-{-]-^-/-(-_-C=:-<-[-}-G=|-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-R-S-T-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;A=_;q;h-r;s;t;", "u;V%v;w;x;A&y;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;`; >.>+>@>#>$>%>&>*>=>->;>>>", ",>'>)>!>~>{>]>^>/>(>_>C=:><>[>}>|>1>2>3>4>5>6>7>8>9>0>@>a>b>5;c>/>d>e>f>g>B;h>i>j>B-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>N>P>Q>R>y=S>T>U>V>W>X>Y>Z>~*`> ,.,+,@,#,$,%,", "&,*,=, ,-,y=;,>,,,',),!,~,{,],^,/,(,_,:,<,~*[,},|,1,2,3,4,5,6,7,8,9,0,O>a,b,c,d,e,f,g,h,i,j,},k,", "l,m,n,o,f,p,q,r,s,t,u,l,v,z=w,x,y,~;z,A,B,C,D,E,F,G,H,F,I,J,K,L,M,N,O,P,Q,R,S,T,I,U,V,W,X,Y,Z,`,", " '.'F,J,+'@'#'W>:,r,$']-%'&'*'='-';'>','''A,)'!'~'T,{']'^'/'('_':'<'['}'|'1'2'3'4'5'6'7'8'9'0'a'", "v,b'c'd'[,e'f'g'h'0,i'X>N>j'U,k'l'm'n'o'p'q'r's't'u'v'w'x'y'z'A'B'b,C'M,D'E'F'X>Z>G'H'I' ,J'K'L'", "M'N'O'P'Q'R'H,S'T'P,U'V'W'X'c,e'I,Y'Z'a,`'!'C' ).)+)k=@)#)$)l,%)<'&)*)=)-)=);)>),)Y'')$'))L']*j,", "!)9'~){))-~*M>])^)/)E'()1'3'C'|'b,_):)<)[)})|)1)2) )3)3)!'O>4)5)E'&)6)[)-)7):)1'8)7,R'9)a'V>0)0)", ")'@'a)7'b)O,!'c)P,_)E'2'd)e)f)%)5)e)1'g)h)i)j)=)k)M,&)*)l)m)2'n)m)o)L,p)q)r)s)t)u)v)(-w)l=x)x)y)", "z)A)B)C)D)E)F)G)H)I)_'J)K)L)M)N)O)P)Q)R)S)T)U)S)R)V)W)X)Y)J)Z)J)`)I) !.!X)+!@!#!$!%!&!*!=!-!&!;!", ">!,!'!'!)!!!~!{!]!^!/!(!_!:!~,~'~)~!~~~{~]~^~/~(~_~:~:~!~<~[~=~<~<~!~}~|~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~p~r~s~t~u~v~w~x~y~u~z~A~B~C~D~D~D~D~C~B~B~E~F~G~H~I~J~J~K~L~M~N~"}; searchandrescue_1.5.0/sar/icons/README0000644000175000017500000000002310104532745016516 0ustar jessejesseCompile time icons searchandrescue_1.5.0/sar/sarfioopen.c0000644000175000017500000020574711344253460017061 0ustar jessejesse#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: * *